or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

build-system.mdconfiguration.mddev-mode.mdindex.mdpackaging.mdutilities.md

dev-mode.mddocs/

0

# Development Mode

1

2

Quarkus development mode provides hot reloading, live coding, development services, and enhanced debugging capabilities to create a seamless developer experience. The development mode infrastructure handles file watching, incremental compilation, and runtime updates without requiring application restarts.

3

4

## Core Imports

5

6

```java

7

// Development mode context and processing

8

import io.quarkus.deployment.dev.DevModeContext;

9

import io.quarkus.deployment.dev.RuntimeUpdatesProcessor;

10

import io.quarkus.deployment.dev.CompilationProvider;

11

import io.quarkus.deployment.dev.DevModeListener;

12

import io.quarkus.deployment.dev.ClassScanResult;

13

14

// File system watching and hot deployment

15

import io.quarkus.deployment.dev.filesystem.StaticFileSystemWatcher;

16

import io.quarkus.deployment.dev.filesystem.ReloadableFileSystemWatcher;

17

import io.quarkus.deployment.dev.HotDeploymentWatchedFileBuildStep;

18

19

// Development services

20

import io.quarkus.deployment.dev.devservices.DevServicesBuildItem;

21

import io.quarkus.deployment.dev.devservices.DevServicesConfig;

22

import io.quarkus.deployment.dev.devservices.DevServicesResultBuildItem;

23

24

// Remote development mode

25

import io.quarkus.deployment.dev.remote.RemoteDevClient;

26

import io.quarkus.deployment.dev.remote.RemoteDevConfig;

27

28

// Testing integration

29

import io.quarkus.deployment.dev.testing.TestSupport;

30

import io.quarkus.deployment.dev.testing.TestConfig;

31

import io.quarkus.deployment.dev.testing.TestRunResults;

32

33

// Console and IDE integration

34

import io.quarkus.deployment.console.ConsoleCommand;

35

import io.quarkus.deployment.console.ConsoleStateManager;

36

import io.quarkus.deployment.ide.EffectiveIdeBuildItem;

37

import io.quarkus.deployment.ide.IdeConfig;

38

```

39

40

## Runtime Updates Processing

41

42

### RuntimeUpdatesProcessor

43

44

Central processor for handling runtime updates and hot reloading.

45

46

```java { .api }

47

class RuntimeUpdatesProcessor {

48

/**

49

* Singleton instance for runtime updates processing

50

*/

51

static RuntimeUpdatesProcessor INSTANCE;

52

53

/**

54

* Scans for changes and triggers updates if necessary

55

*/

56

boolean doScan(boolean userInitiated, boolean forceRestart);

57

58

/**

59

* Adds a hot replacement setup handler

60

*/

61

void addHotReplacementSetup(HotReplacementSetup service);

62

63

/**

64

* Checks for changed classes since last scan

65

*/

66

ClassScanResult checkForChangedClasses();

67

68

/**

69

* Gets the current application context

70

*/

71

DevModeContext getContext();

72

73

/**

74

* Restarts the application completely

75

*/

76

void restart(boolean forceRestart);

77

78

/**

79

* Pauses file watching

80

*/

81

void pause();

82

83

/**

84

* Resumes file watching

85

*/

86

void resume();

87

88

/**

89

* Checks if currently in dev mode

90

*/

91

static boolean isDevMode();

92

}

93

```

94

95

### DevModeContext

96

97

Context object containing development mode configuration and module information.

98

99

```java { .api }

100

class DevModeContext {

101

/**

102

* Gets all modules in the development context

103

*/

104

List<ModuleInfo> getAllModules();

105

106

/**

107

* Gets the main application module

108

*/

109

ModuleInfo getApplicationRoot();

110

111

/**

112

* Gets command line arguments

113

*/

114

String[] getArgs();

115

116

/**

117

* Gets the launch mode

118

*/

119

LaunchMode getLaunchMode();

120

121

/**

122

* Gets the project directory

123

*/

124

Path getProjectDir();

125

126

/**

127

* Checks if this is a test

128

*/

129

boolean isTest();

130

131

/**

132

* Checks if local project dependencies should be disabled

133

*/

134

boolean isLocalProjectDiscovery();

135

136

/**

137

* Information about a module in the development context

138

*/

139

static class ModuleInfo {

140

String getArtifactKey();

141

String getName();

142

Path getProjectDirectory();

143

Path getSourceDirectory();

144

Path getClassesDirectory();

145

Path getResourceDirectory();

146

Set<String> getSourcePaths();

147

CompileClasspathManager getCompileClasspathManager();

148

}

149

}

150

```

151

152

**Usage Examples:**

153

154

```java

155

@BuildStep(onlyIf = IsDevelopment.class)

156

void setupHotReload(DevModeContext context,

157

BuildProducer<HotDeploymentWatchedFileBuildItem> watchedFiles) {

158

159

// Watch configuration files for changes

160

context.getAllModules().forEach(module -> {

161

Path resourceDir = module.getResourceDirectory();

162

if (Files.exists(resourceDir.resolve("application.properties"))) {

163

watchedFiles.produce(new HotDeploymentWatchedFileBuildItem(

164

resourceDir.resolve("application.properties").toString(),

165

true

166

));

167

}

168

});

169

}

170

171

@BuildStep

172

@Record(ExecutionTime.RUNTIME_INIT)

173

void initializeDevMode(DevModeRecorder recorder,

174

LaunchModeBuildItem launchMode,

175

DevModeContext context) {

176

if (launchMode.getLaunchMode() == LaunchMode.DEVELOPMENT) {

177

recorder.setupDevMode(context.getArgs(), context.getProjectDir());

178

}

179

}

180

```

181

182

## File System Watching and Hot Deployment

183

184

### File System Watchers

185

186

```java { .api }

187

class StaticFileSystemWatcher {

188

/**

189

* Watches static resources for changes

190

*/

191

StaticFileSystemWatcher(Path watchedPath,

192

Set<String> includedExtensions,

193

Consumer<Set<String>> changeCallback);

194

195

/**

196

* Starts watching for file changes

197

*/

198

void start();

199

200

/**

201

* Stops file watching

202

*/

203

void stop();

204

}

205

206

class ReloadableFileSystemWatcher {

207

/**

208

* Watches source files for changes requiring compilation

209

*/

210

void watchPath(Path path, String... extensions);

211

212

/**

213

* Gets changed files since last check

214

*/

215

Set<Path> getChangedPaths();

216

217

/**

218

* Resets the changed files tracking

219

*/

220

void reset();

221

}

222

```

223

224

### Hot Deployment Build Items

225

226

```java { .api }

227

class HotDeploymentWatchedFileBuildItem extends MultiBuildItem {

228

/**

229

* Creates a watched file item

230

*/

231

HotDeploymentWatchedFileBuildItem(String location);

232

233

/**

234

* Creates a watched file item with restart behavior

235

*/

236

HotDeploymentWatchedFileBuildItem(String location, boolean restartNeeded);

237

238

String getLocation();

239

boolean isRestartNeeded();

240

}

241

242

class ClassScanResult {

243

/**

244

* Classes that have been added

245

*/

246

Set<String> getAddedClasses();

247

248

/**

249

* Classes that have been modified

250

*/

251

Set<String> getChangedClasses();

252

253

/**

254

* Classes that have been deleted

255

*/

256

Set<String> getDeletedClasses();

257

258

/**

259

* Whether changes require a restart

260

*/

261

boolean isRestartNeeded();

262

}

263

```

264

265

**Usage Examples:**

266

267

```java

268

@BuildStep(onlyIf = IsDevelopment.class)

269

void setupFileWatching(ApplicationArchivesBuildItem archives,

270

BuildProducer<HotDeploymentWatchedFileBuildItem> watchedFiles) {

271

272

// Watch templates for changes

273

watchedFiles.produce(new HotDeploymentWatchedFileBuildItem("templates/", false));

274

275

// Watch configuration that requires restart

276

watchedFiles.produce(new HotDeploymentWatchedFileBuildItem("application.yaml", true));

277

278

// Watch web resources

279

watchedFiles.produce(new HotDeploymentWatchedFileBuildItem("META-INF/resources/", false));

280

}

281

282

public class HotReloadSetup implements HotReplacementSetup {

283

@Override

284

public void setupHotDeployment(HotReplacementContext context) {

285

context.consumeNoRestartChanges(changedResources -> {

286

// Handle resource changes that don't require restart

287

for (String resource : changedResources) {

288

if (resource.endsWith(".html") || resource.endsWith(".css")) {

289

// Refresh web resources

290

refreshWebResource(resource);

291

}

292

}

293

});

294

}

295

}

296

```

297

298

## Compilation Providers

299

300

### CompilationProvider Interface

301

302

Service provider interface for handling compilation of different file types in development mode.

303

304

```java { .api }

305

interface CompilationProvider {

306

/**

307

* File extensions this provider can handle

308

*/

309

Set<String> handledExtensions();

310

311

/**

312

* Compiles the specified files

313

*/

314

void compile(Set<File> filesToCompile, Context context);

315

316

/**

317

* Compilation context providing build information

318

*/

319

interface Context {

320

/**

321

* Source directory for compilation

322

*/

323

Path getSourceDirectory();

324

325

/**

326

* Output directory for compiled classes

327

*/

328

Path getOutputDirectory();

329

330

/**

331

* Classpath for compilation

332

*/

333

ClassLoader getClasspathClassLoader();

334

335

/**

336

* Gets the project directory

337

*/

338

Path getProjectDirectory();

339

340

/**

341

* Gets compiler arguments

342

*/

343

List<String> getCompilerOptions();

344

}

345

}

346

```

347

348

**Implementation Example:**

349

350

```java

351

public class KotlinCompilationProvider implements CompilationProvider {

352

353

@Override

354

public Set<String> handledExtensions() {

355

return Set.of(".kt", ".kts");

356

}

357

358

@Override

359

public void compile(Set<File> filesToCompile, Context context) {

360

if (filesToCompile.isEmpty()) {

361

return;

362

}

363

364

List<String> args = new ArrayList<>();

365

args.add("-cp");

366

args.add(buildClasspath(context));

367

args.add("-d");

368

args.add(context.getOutputDirectory().toString());

369

370

// Add Kotlin-specific options

371

args.addAll(context.getCompilerOptions());

372

373

// Add source files

374

filesToCompile.forEach(file -> args.add(file.getAbsolutePath()));

375

376

// Execute Kotlin compiler

377

KotlinCompiler.exec(args.toArray(new String[0]));

378

}

379

}

380

381

@BuildStep

382

void registerKotlinCompiler(BuildProducer<CompilationProviderBuildItem> providers) {

383

providers.produce(new CompilationProviderBuildItem(KotlinCompilationProvider.class));

384

}

385

```

386

387

## Development Services

388

389

### DevServices Infrastructure

390

391

Development services automatically start external services like databases, message brokers, etc., during development.

392

393

```java { .api }

394

class DevServicesConfig {

395

/**

396

* Whether dev services are enabled globally

397

*/

398

@WithDefault("true")

399

boolean enabled;

400

401

/**

402

* Timeout for starting services

403

*/

404

@WithDefault("60s")

405

Duration timeout;

406

407

/**

408

* Whether to share services between applications

409

*/

410

@WithDefault("true")

411

boolean shared;

412

}

413

414

class DevServicesBuildItem extends MultiBuildItem {

415

/**

416

* Creates a dev service build item

417

*/

418

DevServicesBuildItem(String name,

419

String containerImage,

420

Map<String, String> containerProperties,

421

Map<String, Object> configProperties);

422

423

String getName();

424

String getContainerImage();

425

Map<String, String> getContainerProperties();

426

Map<String, Object> getConfigProperties();

427

}

428

429

class DevServicesResultBuildItem extends SimpleBuildItem {

430

Map<String, String> getConfig();

431

Closeable getCloseable();

432

}

433

```

434

435

**Usage Examples:**

436

437

```java

438

@BuildStep(onlyIf = { IsDevelopment.class, DevServicesEnabled.class })

439

DevServicesBuildItem startDatabase(LaunchModeBuildItem launchMode,

440

DatabaseConfig config) {

441

442

if (config.devservices.enabled && config.url.isEmpty()) {

443

Map<String, String> containerProps = Map.of(

444

"POSTGRES_DB", "devdb",

445

"POSTGRES_USER", "dev",

446

"POSTGRES_PASSWORD", "dev"

447

);

448

449

Map<String, Object> configProps = Map.of(

450

"quarkus.datasource.jdbc.url", "jdbc:postgresql://localhost:5432/devdb",

451

"quarkus.datasource.username", "dev",

452

"quarkus.datasource.password", "dev"

453

);

454

455

return new DevServicesBuildItem(

456

"postgresql",

457

"postgres:13",

458

containerProps,

459

configProps

460

);

461

}

462

return null;

463

}

464

465

@BuildStep

466

DevServicesResultBuildItem configureDevServices(List<DevServicesBuildItem> devServices,

467

LaunchModeBuildItem launchMode) {

468

Map<String, String> combinedConfig = new HashMap<>();

469

List<Closeable> closeables = new ArrayList<>();

470

471

for (DevServicesBuildItem devService : devServices) {

472

// Start container and collect configuration

473

ContainerInfo container = startContainer(devService);

474

combinedConfig.putAll(container.getConfig());

475

closeables.add(container::stop);

476

}

477

478

return new DevServicesResultBuildItem(combinedConfig, () -> {

479

for (Closeable closeable : closeables) {

480

closeable.close();

481

}

482

});

483

}

484

```

485

486

## Console and Command Integration

487

488

### Console Commands

489

490

```java { .api }

491

interface ConsoleCommand {

492

/**

493

* Command name for console input

494

*/

495

String getCommand();

496

497

/**

498

* Description of the command

499

*/

500

String getDescription();

501

502

/**

503

* Executes the command

504

*/

505

void execute(String[] args, ConsoleContext context);

506

507

/**

508

* Whether command is available in current mode

509

*/

510

default boolean isAvailable() { return true; }

511

}

512

513

class ConsoleStateManager {

514

/**

515

* Registers a console command

516

*/

517

void addCommand(ConsoleCommand command);

518

519

/**

520

* Processes console input

521

*/

522

void handleInput(String input);

523

524

/**

525

* Sets up console reading thread

526

*/

527

void setupConsole();

528

}

529

```

530

531

**Implementation Example:**

532

533

```java

534

public class TestCommand implements ConsoleCommand {

535

536

@Override

537

public String getCommand() {

538

return "t";

539

}

540

541

@Override

542

public String getDescription() {

543

return "Run tests";

544

}

545

546

@Override

547

public void execute(String[] args, ConsoleContext context) {

548

TestSupport.runTests();

549

}

550

551

@Override

552

public boolean isAvailable() {

553

return LaunchMode.current() == LaunchMode.DEVELOPMENT;

554

}

555

}

556

557

@BuildStep(onlyIf = IsDevelopment.class)

558

void registerConsoleCommands(BuildProducer<ConsoleCommandBuildItem> commands) {

559

commands.produce(new ConsoleCommandBuildItem(new TestCommand()));

560

commands.produce(new ConsoleCommandBuildItem(new RestartCommand()));

561

commands.produce(new ConsoleCommandBuildItem(new HelpCommand()));

562

}

563

```

564

565

## Remote Development Mode

566

567

### Remote Development Client

568

569

```java { .api }

570

class RemoteDevClient {

571

/**

572

* Connects to remote development server

573

*/

574

static RemoteDevClient connect(RemoteDevConfig config);

575

576

/**

577

* Sends local changes to remote server

578

*/

579

void sendChanges(Set<Path> changedFiles);

580

581

/**

582

* Receives updates from remote server

583

*/

584

void receiveUpdates();

585

586

/**

587

* Disconnects from remote server

588

*/

589

void disconnect();

590

}

591

592

class RemoteDevConfig {

593

/**

594

* Remote server URL

595

*/

596

String url;

597

598

/**

599

* Authentication token

600

*/

601

Optional<String> password;

602

603

/**

604

* Connection timeout

605

*/

606

@WithDefault("30s")

607

Duration connectTimeout;

608

}

609

```

610

611

**Usage Example:**

612

613

```java

614

@BuildStep(onlyIf = { IsDevelopment.class, RemoteDevEnabled.class })

615

@Record(ExecutionTime.RUNTIME_INIT)

616

void setupRemoteDev(RemoteDevRecorder recorder,

617

RemoteDevConfig config,

618

DevModeContext context) {

619

620

recorder.setupRemoteDevClient(

621

config.url,

622

config.password.orElse(null),

623

context.getProjectDir()

624

);

625

}

626

```

627

628

## Testing Integration

629

630

### Development Mode Testing

631

632

```java { .api }

633

class TestSupport {

634

/**

635

* Runs all tests in development mode

636

*/

637

static TestRunResults runTests();

638

639

/**

640

* Runs specific test classes

641

*/

642

static TestRunResults runTests(Set<String> testClasses);

643

644

/**

645

* Checks if tests are currently running

646

*/

647

static boolean isRunning();

648

649

/**

650

* Gets the last test results

651

*/

652

static Optional<TestRunResults> getLastResults();

653

}

654

655

class TestRunResults {

656

long getTestsRun();

657

long getTestsSkipped();

658

long getTestsFailed();

659

Duration getDuration();

660

List<TestFailure> getFailures();

661

}

662

663

class TestConfig {

664

/**

665

* Whether to run tests automatically on changes

666

*/

667

@WithDefault("false")

668

boolean continuous;

669

670

/**

671

* Test framework to use

672

*/

673

@WithDefault("junit5")

674

TestFramework framework;

675

676

/**

677

* Include patterns for test discovery

678

*/

679

List<String> includePattern;

680

681

/**

682

* Exclude patterns for test discovery

683

*/

684

List<String> excludePattern;

685

}

686

```

687

688

**Usage Example:**

689

690

```java

691

@BuildStep(onlyIf = IsDevelopment.class)

692

@Record(ExecutionTime.RUNTIME_INIT)

693

void setupTestSupport(TestRecorder recorder,

694

TestConfig config,

695

ApplicationIndexBuildItem index) {

696

697

List<String> testClasses = index.getIndex()

698

.getAllKnownImplementors(DotName.createSimple("org.junit.jupiter.api.Test"))

699

.stream()

700

.map(classInfo -> classInfo.name().toString())

701

.collect(Collectors.toList());

702

703

recorder.setupTestSupport(testClasses, config.continuous);

704

}

705

```

706

707

## IDE Integration

708

709

### IDE Configuration and Support

710

711

```java { .api }

712

class IdeConfig {

713

/**

714

* Target IDE for integration

715

*/

716

Optional<IdeType> target;

717

718

/**

719

* Whether to open URLs in IDE

720

*/

721

@WithDefault("true")

722

boolean openUrls;

723

724

enum IdeType {

725

IDEA, ECLIPSE, VSCODE, NETBEANS

726

}

727

}

728

729

class EffectiveIdeBuildItem extends SimpleBuildItem {

730

Optional<IdeType> getIdeType();

731

boolean isIdePresent();

732

733

/**

734

* Opens a file in the IDE at specific line

735

*/

736

void openFile(Path file, int line);

737

738

/**

739

* Opens a URL in the IDE

740

*/

741

void openUrl(String url);

742

}

743

```

744

745

**Usage Example:**

746

747

```java

748

@BuildStep

749

EffectiveIdeBuildItem detectIde(IdeConfig config) {

750

// Detect IDE based on environment variables, system properties, etc.

751

Optional<IdeType> detectedIde = detectCurrentIde();

752

753

IdeType effectiveIde = config.target.orElse(detectedIde.orElse(null));

754

755

return new EffectiveIdeBuildItem(Optional.ofNullable(effectiveIde));

756

}

757

758

@BuildStep(onlyIf = IsDevelopment.class)

759

void setupIdeIntegration(EffectiveIdeBuildItem ide,

760

BuildProducer<ConsoleCommandBuildItem> commands) {

761

762

if (ide.isIdePresent()) {

763

commands.produce(new ConsoleCommandBuildItem(new OpenInIdeCommand(ide)));

764

}

765

}

766

```