or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

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

utilities.mddocs/

0

# Utilities

1

2

Quarkus Core Deployment provides a comprehensive set of utility classes for common deployment-time operations including reflection, file system operations, service loading, artifact handling, container runtime detection, and various helper functions that support the build and deployment process.

3

4

## Core Imports

5

6

```java

7

// Reflection utilities

8

import io.quarkus.deployment.util.ReflectUtil;

9

import io.quarkus.deployment.util.ClassUtil;

10

import io.quarkus.deployment.util.DeploymentUtil;

11

12

// Service loading utilities

13

import io.quarkus.deployment.util.ServiceUtil;

14

15

// File system utilities

16

import io.quarkus.deployment.util.FileUtil;

17

import io.quarkus.deployment.util.IoUtil;

18

import io.quarkus.deployment.util.PathUtil;

19

20

// Artifact and dependency utilities

21

import io.quarkus.deployment.util.ArtifactInfoUtil;

22

import io.quarkus.deployment.util.ArtifactResultBuilder;

23

24

// Container runtime utilities

25

import io.quarkus.deployment.util.ContainerRuntimeUtil;

26

import io.quarkus.deployment.util.ProcessUtil;

27

28

// Hashing and validation utilities

29

import io.quarkus.deployment.util.HashUtil;

30

import io.quarkus.deployment.util.StringUtil;

31

32

// Bean and proxy utilities

33

import io.quarkus.deployment.bean.BeanArchiveIndex;

34

import io.quarkus.deployment.bean.JavaBeanUtil;

35

import io.quarkus.deployment.proxy.ProxyFactory;

36

37

// Type parsing and handling

38

import io.quarkus.deployment.types.ParsedType;

39

import io.quarkus.deployment.types.TypeParser;

40

41

// Code generation framework

42

import io.quarkus.deployment.CodeGenProvider;

43

import io.quarkus.deployment.CodeGenContext;

44

import io.quarkus.deployment.CodeGenerator;

45

import io.quarkus.bootstrap.prebuild.CodeGenException;

46

```

47

48

## Reflection Utilities

49

50

### ReflectUtil

51

52

Comprehensive reflection utilities for deployment-time introspection and manipulation.

53

54

```java { .api }

55

class ReflectUtil {

56

/**

57

* Gets a method by name and parameter types

58

*/

59

static Method getMethod(Class<?> clazz, String name, Class<?>... parameterTypes)

60

throws NoSuchMethodException;

61

62

/**

63

* Gets a field by name

64

*/

65

static Field getField(Class<?> clazz, String name)

66

throws NoSuchFieldException;

67

68

/**

69

* Creates a new instance using default constructor

70

*/

71

static <T> T newInstance(Class<T> clazz);

72

73

/**

74

* Creates a new instance using constructor with parameters

75

*/

76

static <T> T newInstance(Class<T> clazz, Class<?>[] paramTypes, Object... args);

77

78

/**

79

* Invokes a method on an instance

80

*/

81

static Object invoke(Method method, Object instance, Object... args);

82

83

/**

84

* Invokes a static method

85

*/

86

static Object invokeStatic(Method method, Object... args);

87

88

/**

89

* Gets or sets a field value

90

*/

91

static Object getFieldValue(Field field, Object instance);

92

static void setFieldValue(Field field, Object instance, Object value);

93

94

/**

95

* Finds all methods with given annotation

96

*/

97

static List<Method> getMethodsWithAnnotation(Class<?> clazz,

98

Class<? extends Annotation> annotation);

99

100

/**

101

* Finds all fields with given annotation

102

*/

103

static List<Field> getFieldsWithAnnotation(Class<?> clazz,

104

Class<? extends Annotation> annotation);

105

106

/**

107

* Gets raw class from parameterized type

108

*/

109

static Class<?> getRawType(Type type);

110

111

/**

112

* Checks if class is assignable from type

113

*/

114

static boolean isAssignableFrom(Class<?> clazz, Type type);

115

}

116

```

117

118

**Usage Examples:**

119

120

```java

121

@BuildStep

122

void processReflectiveAccess(CombinedIndexBuildItem index,

123

BuildProducer<ReflectiveClassBuildItem> reflectiveClasses) {

124

125

// Find all classes with @Entity annotation

126

Collection<AnnotationInstance> entities = index.getIndex()

127

.getAnnotations(DotName.createSimple("javax.persistence.Entity"));

128

129

for (AnnotationInstance entity : entities) {

130

String className = entity.target().asClass().name().toString();

131

132

try {

133

Class<?> entityClass = Class.forName(className);

134

135

// Register class for reflection

136

reflectiveClasses.produce(ReflectiveClassBuildItem.builder(entityClass)

137

.constructors()

138

.methods()

139

.fields()

140

.build());

141

142

// Check for getter/setter methods

143

List<Method> getters = ReflectUtil.getMethodsWithAnnotation(

144

entityClass, Getter.class);

145

List<Method> setters = ReflectUtil.getMethodsWithAnnotation(

146

entityClass, Setter.class);

147

148

} catch (ClassNotFoundException e) {

149

// Handle missing class

150

}

151

}

152

}

153

154

@BuildStep

155

@Record(ExecutionTime.STATIC_INIT)

156

void setupReflection(MyRecorder recorder) {

157

// Use reflection to configure framework

158

recorder.configure(ReflectUtil.class);

159

}

160

```

161

162

## Service Loading Utilities

163

164

### ServiceUtil

165

166

Utilities for loading and managing service implementations via ServiceLoader.

167

168

```java { .api }

169

class ServiceUtil {

170

/**

171

* Loads all implementations of a service from classpath

172

*/

173

static <T> List<T> classPathServices(Class<T> serviceType, ClassLoader classLoader);

174

175

/**

176

* Loads first implementation of a service

177

*/

178

static <T> Optional<T> classPathService(Class<T> serviceType, ClassLoader classLoader);

179

180

/**

181

* Loads services with specific context class loader

182

*/

183

static <T> List<T> loadServices(Class<T> serviceType, ClassLoader classLoader);

184

185

/**

186

* Gets service implementation classes (not instances)

187

*/

188

static <T> List<Class<? extends T>> loadServiceClasses(Class<T> serviceType,

189

ClassLoader classLoader);

190

191

/**

192

* Checks if service implementation exists

193

*/

194

static boolean hasService(Class<?> serviceType, ClassLoader classLoader);

195

196

/**

197

* Creates service loader for given type

198

*/

199

static <T> ServiceLoader<T> load(Class<T> serviceType, ClassLoader classLoader);

200

}

201

```

202

203

**Usage Examples:**

204

205

```java

206

@BuildStep

207

void discoverCompilationProviders(BuildProducer<CompilationProviderBuildItem> providers) {

208

209

// Load all compilation providers from classpath

210

List<CompilationProvider> compilationProviders =

211

ServiceUtil.classPathServices(CompilationProvider.class,

212

Thread.currentThread().getContextClassLoader());

213

214

for (CompilationProvider provider : compilationProviders) {

215

providers.produce(new CompilationProviderBuildItem(provider.getClass()));

216

}

217

}

218

219

@BuildStep

220

void configureCodeGenerators(BuildProducer<CodeGenProviderBuildItem> codeGenProviders) {

221

222

// Check if specific code generator is available

223

if (ServiceUtil.hasService(GrpcCodeGenProvider.class,

224

Thread.currentThread().getContextClassLoader())) {

225

226

Optional<GrpcCodeGenProvider> provider = ServiceUtil.classPathService(

227

GrpcCodeGenProvider.class,

228

Thread.currentThread().getContextClassLoader());

229

230

if (provider.isPresent()) {

231

codeGenProviders.produce(new CodeGenProviderBuildItem(provider.get()));

232

}

233

}

234

}

235

```

236

237

## File System Utilities

238

239

### FileUtil

240

241

Comprehensive file system operations for deployment processing.

242

243

```java { .api }

244

class FileUtil {

245

/**

246

* Copies a file from source to target

247

*/

248

static void copyFile(Path source, Path target) throws IOException;

249

250

/**

251

* Copies directory recursively

252

*/

253

static void copyDirectory(Path source, Path target) throws IOException;

254

255

/**

256

* Moves file or directory

257

*/

258

static void moveFile(Path source, Path target) throws IOException;

259

260

/**

261

* Deletes file or directory recursively

262

*/

263

static void deleteDirectory(Path directory) throws IOException;

264

static boolean deleteIfExists(Path path) throws IOException;

265

266

/**

267

* Creates directories if they don't exist

268

*/

269

static Path ensureDirectoryExists(Path directory) throws IOException;

270

271

/**

272

* Checks if directory is empty

273

*/

274

static boolean isDirectoryEmpty(Path directory) throws IOException;

275

276

/**

277

* Gets relative path between two paths

278

*/

279

static String relativize(Path base, Path child);

280

281

/**

282

* Reads file content as string

283

*/

284

static String readFileToString(Path file, StandardCharsets charset) throws IOException;

285

286

/**

287

* Writes string content to file

288

*/

289

static void writeStringToFile(Path file, String content, StandardCharsets charset)

290

throws IOException;

291

292

/**

293

* Lists files in directory with filter

294

*/

295

static List<Path> listFiles(Path directory, String... extensions) throws IOException;

296

297

/**

298

* Finds files recursively with pattern

299

*/

300

static List<Path> findFiles(Path directory, String pattern) throws IOException;

301

}

302

```

303

304

### IoUtil

305

306

Lower-level I/O utilities and stream operations.

307

308

```java { .api }

309

class IoUtil {

310

/**

311

* Reads all bytes from input stream

312

*/

313

static byte[] readBytes(InputStream inputStream) throws IOException;

314

315

/**

316

* Copies input stream to output stream

317

*/

318

static long copy(InputStream input, OutputStream output) throws IOException;

319

320

/**

321

* Reads properties from input stream

322

*/

323

static Properties readProperties(InputStream inputStream) throws IOException;

324

325

/**

326

* Creates buffered reader for path

327

*/

328

static BufferedReader newBufferedReader(Path path, Charset charset) throws IOException;

329

330

/**

331

* Creates buffered writer for path

332

*/

333

static BufferedWriter newBufferedWriter(Path path, Charset charset) throws IOException;

334

335

/**

336

* Safely closes multiple closeables

337

*/

338

static void safeClose(Closeable... closeables);

339

}

340

```

341

342

**Usage Examples:**

343

344

```java

345

@BuildStep

346

void processConfigurationFiles(ApplicationArchivesBuildItem archives,

347

BuildProducer<ConfigurationBuildItem> config) throws IOException {

348

349

for (ApplicationArchive archive : archives.getAllApplicationArchives()) {

350

Path resourceDir = archive.apply(tree -> {

351

OpenPathTree.PathVisit visit = tree.visit("META-INF");

352

return visit != null ? visit.getPath() : null;

353

});

354

355

if (resourceDir != null) {

356

// Find all .properties files

357

List<Path> propFiles = FileUtil.findFiles(resourceDir, "*.properties");

358

359

for (Path propFile : propFiles) {

360

Properties props = new Properties();

361

try (InputStream is = Files.newInputStream(propFile)) {

362

props = IoUtil.readProperties(is);

363

}

364

365

// Process properties

366

processConfigProperties(props);

367

}

368

}

369

}

370

}

371

372

@BuildStep

373

void generateConfigurationFiles(ConfigurationBuildItem config,

374

BuildProducer<GeneratedResourceBuildItem> resources)

375

throws IOException {

376

377

Path tempDir = Files.createTempDirectory("quarkus-config");

378

try {

379

// Generate configuration file

380

Path configFile = tempDir.resolve("runtime-config.properties");

381

382

Properties runtimeProps = new Properties();

383

config.getPropertyNames().forEach(name -> {

384

runtimeProps.setProperty(name, config.getValue(name, String.class).orElse(""));

385

});

386

387

try (OutputStream os = Files.newOutputStream(configFile)) {

388

runtimeProps.store(os, "Generated runtime configuration");

389

}

390

391

// Read generated content

392

byte[] content = FileUtil.readFileToString(configFile, StandardCharsets.UTF_8)

393

.getBytes(StandardCharsets.UTF_8);

394

395

resources.produce(new GeneratedResourceBuildItem(

396

"META-INF/quarkus-runtime-config.properties", content));

397

398

} finally {

399

FileUtil.deleteDirectory(tempDir);

400

}

401

}

402

```

403

404

## Code Generation Framework

405

406

Quarkus provides a comprehensive code generation framework that allows extensions to generate source code during the build process. This system enables build-time code generation from various input formats including protobuf, OpenAPI, GraphQL schemas, and custom domain-specific languages.

407

408

### CodeGenProvider

409

410

Interface for implementing custom code generators that run during the generate-sources phase.

411

412

```java { .api }

413

interface CodeGenProvider {

414

/**

415

* Unique identifier for this code generator, corresponds to the directory

416

* name in generated-sources

417

*/

418

String providerId();

419

420

/**

421

* File extensions that this code generator can process

422

*/

423

String[] inputExtensions();

424

425

/**

426

* Name of the input directory relative to source roots

427

* For example: src/main/{inputDirectory} and src/test/{inputDirectory}

428

*/

429

String inputDirectory();

430

431

/**

432

* Optional absolute path override for input directory

433

* Called after init(), returning null uses default inputDirectory()

434

*/

435

default Path getInputDirectory() { return null; }

436

437

/**

438

* Initialize the provider with application model and build properties

439

*/

440

default void init(ApplicationModel model, Map<String, String> properties) {}

441

442

/**

443

* Trigger code generation process

444

* @param context Code generation context with paths and configuration

445

* @return true if any files were generated or modified

446

*/

447

boolean trigger(CodeGenContext context) throws CodeGenException;

448

449

/**

450

* Determine if code generator should run based on source directory and config

451

*/

452

default boolean shouldRun(Path sourceDir, Config config) {

453

return Files.isDirectory(sourceDir);

454

}

455

}

456

```

457

458

### CodeGenContext

459

460

Context object providing all necessary information for code generation.

461

462

```java { .api }

463

class CodeGenContext {

464

/**

465

* Application model with dependency information

466

*/

467

ApplicationModel applicationModel();

468

469

/**

470

* Target directory for generated output

471

* Typically: target/generated-sources/{providerId}

472

*/

473

Path outDir();

474

475

/**

476

* Working directory (typically project build directory)

477

*/

478

Path workDir();

479

480

/**

481

* Input directory containing source files to process

482

* Typically: src/main/{inputDirectory} or src/test/{inputDirectory}

483

*/

484

Path inputDir();

485

486

/**

487

* Whether spawned processes should redirect I/O streams

488

*/

489

boolean shouldRedirectIO();

490

491

/**

492

* Build-time configuration

493

*/

494

Config config();

495

496

/**

497

* Whether generation is for tests (true) or main sources (false)

498

*/

499

boolean test();

500

}

501

```

502

503

### CodeGenerator

504

505

Static utility class for initializing and executing code generators.

506

507

```java { .api }

508

class CodeGenerator {

509

/**

510

* Initialize and run all code generators for given parameters

511

*/

512

static void initAndRun(

513

QuarkusClassLoader classLoader,

514

PathCollection sourceParentDirs,

515

Path generatedSourcesDir,

516

Path buildDir,

517

Consumer<Path> sourceRegistrar,

518

ApplicationModel appModel,

519

Properties properties,

520

String launchMode,

521

boolean test

522

) throws CodeGenException;

523

524

/**

525

* Trigger a specific code generator

526

*/

527

static boolean trigger(

528

ClassLoader deploymentClassLoader,

529

CodeGenData data,

530

ApplicationModel appModel,

531

Config config,

532

boolean test

533

) throws CodeGenException;

534

535

/**

536

* Get build-time configuration for code generation

537

*/

538

static Config getConfig(

539

ApplicationModel appModel,

540

LaunchMode launchMode,

541

Properties buildSystemProps,

542

QuarkusClassLoader deploymentClassLoader

543

) throws CodeGenException;

544

}

545

```

546

547

**Usage Examples:**

548

549

```java

550

/**

551

* Example: Protocol Buffer code generator

552

*/

553

public class ProtobufCodeGenProvider implements CodeGenProvider {

554

555

@Override

556

public String providerId() {

557

return "protobuf";

558

}

559

560

@Override

561

public String[] inputExtensions() {

562

return new String[]{"proto"};

563

}

564

565

@Override

566

public String inputDirectory() {

567

return "proto";

568

}

569

570

@Override

571

public void init(ApplicationModel model, Map<String, String> properties) {

572

// Initialize protoc compiler path, output options, etc.

573

this.protocPath = properties.get("protoc.path");

574

this.javaOut = Boolean.parseBoolean(properties.get("protobuf.java.out"));

575

}

576

577

@Override

578

public boolean trigger(CodeGenContext context) throws CodeGenException {

579

Path inputDir = context.inputDir();

580

Path outputDir = context.outDir();

581

582

if (!Files.exists(inputDir)) {

583

return false;

584

}

585

586

boolean generated = false;

587

try (Stream<Path> protoFiles = Files.walk(inputDir)) {

588

List<Path> protoSources = protoFiles

589

.filter(p -> p.toString().endsWith(".proto"))

590

.collect(Collectors.toList());

591

592

if (!protoSources.isEmpty()) {

593

// Run protoc compiler

594

List<String> command = List.of(

595

protocPath,

596

"--java_out=" + outputDir,

597

"--proto_path=" + inputDir

598

);

599

command.addAll(protoSources.stream()

600

.map(Path::toString)

601

.collect(Collectors.toList()));

602

603

ProcessBuilder pb = new ProcessBuilder(command);

604

if (context.shouldRedirectIO()) {

605

pb.inheritIO();

606

}

607

608

Process process = pb.start();

609

int exitCode = process.waitFor();

610

611

if (exitCode != 0) {

612

throw new CodeGenException("protoc compilation failed with exit code: " + exitCode);

613

}

614

615

generated = true;

616

}

617

} catch (IOException | InterruptedException e) {

618

throw new CodeGenException("Protocol buffer code generation failed", e);

619

}

620

621

return generated;

622

}

623

624

@Override

625

public boolean shouldRun(Path sourceDir, Config config) {

626

return Files.isDirectory(sourceDir) &&

627

config.getOptionalValue("quarkus.protobuf.enabled", Boolean.class).orElse(true);

628

}

629

}

630

631

/**

632

* Build step that configures code generation

633

*/

634

@BuildStep

635

void configureCodeGeneration(BuildProducer<CodeGenProviderBuildItem> codeGenProviders) {

636

codeGenProviders.produce(new CodeGenProviderBuildItem(ProtobufCodeGenProvider.class.getName()));

637

}

638

639

/**

640

* Integration with development mode

641

*/

642

@BuildStep

643

void setupDevModeCodeGeneration(LaunchModeBuildItem launchMode,

644

BuildProducer<HotDeploymentWatchedFileBuildItem> watchedFiles) {

645

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

646

// Watch .proto files for changes

647

watchedFiles.produce(HotDeploymentWatchedFileBuildItem.builder()

648

.setLocationGlob("src/main/proto/**/*.proto")

649

.setRestartNeeded(true)

650

.build());

651

}

652

}

653

```

654

655

## Artifact and Dependency Utilities

656

657

### ArtifactInfoUtil

658

659

Utilities for working with Maven artifacts and dependency information.

660

661

```java { .api }

662

class ArtifactInfoUtil {

663

/**

664

* Parses artifact coordinates from string

665

*/

666

static ArtifactKey parseArtifactKey(String coords);

667

668

/**

669

* Creates artifact key from components

670

*/

671

static ArtifactKey createArtifactKey(String groupId, String artifactId,

672

String classifier, String type);

673

674

/**

675

* Gets artifact version from dependency

676

*/

677

static String getArtifactVersion(ResolvedDependency dependency);

678

679

/**

680

* Checks if artifact matches pattern

681

*/

682

static boolean matches(ArtifactKey artifact, String pattern);

683

684

/**

685

* Gets all transitive dependencies

686

*/

687

static Set<ResolvedDependency> getTransitiveDependencies(

688

ResolvedDependency rootDependency,

689

boolean includeOptional

690

);

691

692

/**

693

* Filters dependencies by scope

694

*/

695

static List<ResolvedDependency> filterByScope(

696

List<ResolvedDependency> dependencies,

697

String... scopes

698

);

699

700

/**

701

* Creates dependency tree string representation

702

*/

703

static String createDependencyTree(ApplicationModel applicationModel);

704

}

705

```

706

707

**Usage Examples:**

708

709

```java

710

@BuildStep

711

void analyzeDependencies(ApplicationArchivesBuildItem archives,

712

BuildProducer<DependencyAnalysisBuildItem> analysis) {

713

714

List<ResolvedDependency> runtimeDeps = new ArrayList<>();

715

716

for (ApplicationArchive archive : archives.getApplicationArchives()) {

717

ResolvedDependency dependency = archive.getResolvedDependency();

718

719

if (dependency != null) {

720

// Filter runtime dependencies

721

if (ArtifactInfoUtil.filterByScope(List.of(dependency), "compile", "runtime")

722

.contains(dependency)) {

723

runtimeDeps.add(dependency);

724

}

725

726

// Check for specific artifacts

727

if (ArtifactInfoUtil.matches(dependency.getKey(), "org.hibernate.*")) {

728

// Handle Hibernate dependency

729

handleHibernateDependency(dependency);

730

}

731

}

732

}

733

734

analysis.produce(new DependencyAnalysisBuildItem(runtimeDeps));

735

}

736

```

737

738

## Container Runtime Utilities

739

740

### ContainerRuntimeUtil

741

742

Utilities for detecting and working with container runtimes like Docker and Podman.

743

744

```java { .api }

745

class ContainerRuntimeUtil {

746

/**

747

* Detects available container runtime

748

*/

749

static Optional<ContainerRuntime> detectContainerRuntime();

750

751

/**

752

* Checks if container runtime is available

753

*/

754

static boolean isContainerRuntimeAvailable();

755

756

/**

757

* Gets container runtime executable path

758

*/

759

static Optional<String> getContainerRuntimeExecutable();

760

761

/**

762

* Executes container command

763

*/

764

static ProcessResult executeContainerCommand(List<String> command,

765

Path workingDirectory)

766

throws IOException;

767

768

/**

769

* Builds container image

770

*/

771

static ProcessResult buildImage(Path dockerfile,

772

String imageName,

773

Path context) throws IOException;

774

775

/**

776

* Runs container

777

*/

778

static ProcessResult runContainer(String imageName,

779

Map<String, String> env,

780

List<String> ports,

781

List<String> volumes) throws IOException;

782

783

enum ContainerRuntime {

784

DOCKER("docker"),

785

PODMAN("podman");

786

787

String getExecutableName();

788

List<String> getDefaultOptions();

789

}

790

}

791

```

792

793

### ProcessUtil

794

795

Utilities for executing external processes.

796

797

```java { .api }

798

class ProcessUtil {

799

/**

800

* Executes process with arguments

801

*/

802

static ProcessResult execute(List<String> command,

803

Path workingDirectory,

804

Map<String, String> environment,

805

Duration timeout) throws IOException;

806

807

/**

808

* Executes process and returns result

809

*/

810

static ProcessResult executeAndWait(String... command) throws IOException;

811

812

/**

813

* Checks if executable is available in PATH

814

*/

815

static boolean isExecutableInPath(String executable);

816

817

/**

818

* Gets executable path

819

*/

820

static Optional<Path> findExecutable(String executable);

821

822

/**

823

* Process execution result

824

*/

825

static class ProcessResult {

826

int getExitCode();

827

String getStdout();

828

String getStderr();

829

boolean isSuccess();

830

Duration getDuration();

831

}

832

}

833

```

834

835

**Usage Examples:**

836

837

```java

838

@BuildStep(onlyIf = ContainerImageRequested.class)

839

void buildContainerImage(JarBuildItem jar,

840

ImageConfig imageConfig,

841

BuildProducer<ContainerImageBuildItem> containerImage)

842

throws IOException {

843

844

if (!ContainerRuntimeUtil.isContainerRuntimeAvailable()) {

845

throw new RuntimeException("No container runtime available for image building");

846

}

847

848

ContainerRuntime runtime = ContainerRuntimeUtil.detectContainerRuntime()

849

.orElseThrow(() -> new RuntimeException("Container runtime detection failed"));

850

851

// Generate Dockerfile

852

Path dockerfile = generateDockerfile(jar, imageConfig);

853

854

// Build image

855

String imageName = "quarkus-app:latest";

856

ProcessResult result = ContainerRuntimeUtil.buildImage(

857

dockerfile,

858

imageName,

859

jar.getPath().getParent()

860

);

861

862

if (!result.isSuccess()) {

863

throw new RuntimeException("Container image build failed: " + result.getStderr());

864

}

865

866

containerImage.produce(new ContainerImageBuildItem(imageName));

867

}

868

```

869

870

## Hash and Validation Utilities

871

872

### HashUtil

873

874

Utilities for generating hashes and checksums.

875

876

```java { .api }

877

class HashUtil {

878

/**

879

* Generates SHA-256 hash of file

880

*/

881

static String sha256(Path file) throws IOException;

882

883

/**

884

* Generates SHA-256 hash of bytes

885

*/

886

static String sha256(byte[] data);

887

888

/**

889

* Generates MD5 hash of file

890

*/

891

static String md5(Path file) throws IOException;

892

893

/**

894

* Generates hash using specified algorithm

895

*/

896

static String hash(Path file, String algorithm) throws IOException;

897

898

/**

899

* Verifies file against checksum

900

*/

901

static boolean verify(Path file, String expectedHash, String algorithm) throws IOException;

902

903

/**

904

* Generates hash of directory contents

905

*/

906

static String directoryHash(Path directory, String algorithm) throws IOException;

907

}

908

```

909

910

### StringUtil

911

912

String manipulation and validation utilities.

913

914

```java { .api }

915

class StringUtil {

916

/**

917

* Converts string to kebab-case

918

*/

919

static String toKebabCase(String input);

920

921

/**

922

* Converts string to camelCase

923

*/

924

static String toCamelCase(String input);

925

926

/**

927

* Converts string to PascalCase

928

*/

929

static String toPascalCase(String input);

930

931

/**

932

* Checks if string is null or empty

933

*/

934

static boolean isNullOrEmpty(String str);

935

936

/**

937

* Checks if string is null, empty, or whitespace

938

*/

939

static boolean isNullOrBlank(String str);

940

941

/**

942

* Joins strings with delimiter

943

*/

944

static String join(String delimiter, String... parts);

945

static String join(String delimiter, Collection<String> parts);

946

947

/**

948

* Splits string and trims whitespace

949

*/

950

static List<String> splitAndTrim(String input, String delimiter);

951

952

/**

953

* Replaces placeholders in template

954

*/

955

static String substitute(String template, Map<String, String> replacements);

956

}

957

```

958

959

**Usage Examples:**

960

961

```java

962

@BuildStep

963

void generateHashManifest(JarBuildItem jar,

964

BuildProducer<GeneratedResourceBuildItem> resources) throws IOException {

965

966

// Generate hash of JAR file

967

String jarHash = HashUtil.sha256(jar.getPath());

968

969

// Generate hash of dependencies

970

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

971

if (jar.getLibraryDir().isPresent()) {

972

List<Path> libFiles = FileUtil.listFiles(jar.getLibraryDir().get(), "jar");

973

for (Path libFile : libFiles) {

974

String hash = HashUtil.sha256(libFile);

975

dependencyHashes.put(libFile.getFileName().toString(), hash);

976

}

977

}

978

979

// Create manifest content

980

StringBuilder manifest = new StringBuilder();

981

manifest.append("application.jar=").append(jarHash).append("\n");

982

dependencyHashes.forEach((name, hash) ->

983

manifest.append("lib/").append(name).append("=").append(hash).append("\n"));

984

985

resources.produce(new GeneratedResourceBuildItem(

986

"META-INF/quarkus-hash-manifest.txt",

987

manifest.toString().getBytes(StandardCharsets.UTF_8)

988

));

989

}

990

991

@BuildStep

992

void processConfigurationKeys(ConfigurationBuildItem config,

993

BuildProducer<ConfigKeyBuildItem> configKeys) {

994

995

// Convert configuration keys to different naming conventions

996

for (String propertyName : config.getPropertyNames()) {

997

String kebabCase = StringUtil.toKebabCase(propertyName);

998

String camelCase = StringUtil.toCamelCase(propertyName);

999

1000

configKeys.produce(new ConfigKeyBuildItem(propertyName, kebabCase, camelCase));

1001

}

1002

}

1003

```

1004

1005

## Bean and Proxy Utilities

1006

1007

### JavaBeanUtil

1008

1009

Utilities for working with JavaBeans and property introspection.

1010

1011

```java { .api }

1012

class JavaBeanUtil {

1013

/**

1014

* Gets bean properties for class

1015

*/

1016

static List<PropertyDescriptor> getBeanProperties(Class<?> beanClass);

1017

1018

/**

1019

* Checks if method is a getter

1020

*/

1021

static boolean isGetter(Method method);

1022

1023

/**

1024

* Checks if method is a setter

1025

*/

1026

static boolean isSetter(Method method);

1027

1028

/**

1029

* Gets property name from getter/setter method

1030

*/

1031

static String getPropertyName(Method method);

1032

1033

/**

1034

* Gets property type

1035

*/

1036

static Class<?> getPropertyType(PropertyDescriptor property);

1037

1038

/**

1039

* Sets property value using setter

1040

*/

1041

static void setProperty(Object bean, String propertyName, Object value);

1042

1043

/**

1044

* Gets property value using getter

1045

*/

1046

static Object getProperty(Object bean, String propertyName);

1047

}

1048

```

1049

1050

### ProxyFactory

1051

1052

Factory for creating runtime proxies for interfaces.

1053

1054

```java { .api }

1055

class ProxyFactory {

1056

/**

1057

* Creates proxy for interface with invocation handler

1058

*/

1059

static <T> T createProxy(Class<T> interfaceType,

1060

InvocationHandler handler,

1061

ClassLoader classLoader);

1062

1063

/**

1064

* Creates proxy class for interface

1065

*/

1066

static Class<?> createProxyClass(Class<?>[] interfaces,

1067

ClassLoader classLoader);

1068

1069

/**

1070

* Checks if class is a proxy class

1071

*/

1072

static boolean isProxyClass(Class<?> clazz);

1073

}

1074

```

1075

1076

**Usage Examples:**

1077

1078

```java

1079

@BuildStep

1080

void processConfigurationBeans(CombinedIndexBuildItem index,

1081

BuildProducer<ConfigBeanBuildItem> configBeans) {

1082

1083

// Find classes annotated with @ConfigProperties

1084

Collection<AnnotationInstance> configProperties = index.getIndex()

1085

.getAnnotations(DotName.createSimple("io.quarkus.arc.config.ConfigProperties"));

1086

1087

for (AnnotationInstance annotation : configProperties) {

1088

String className = annotation.target().asClass().name().toString();

1089

1090

try {

1091

Class<?> configClass = Class.forName(className);

1092

1093

// Get bean properties

1094

List<PropertyDescriptor> properties = JavaBeanUtil.getBeanProperties(configClass);

1095

1096

for (PropertyDescriptor property : properties) {

1097

String configKey = StringUtil.toKebabCase(property.getName());

1098

configBeans.produce(new ConfigBeanBuildItem(

1099

configClass,

1100

property.getName(),

1101

configKey,

1102

property.getPropertyType()

1103

));

1104

}

1105

1106

} catch (ClassNotFoundException e) {

1107

// Handle missing class

1108

}

1109

}

1110

}

1111

```