or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

build-time.mdc-interop.mdindex.mdruntime-core.md

build-time.mddocs/

0

# Build-time Configuration

1

2

Build-time APIs for customizing native image generation, including feature registration, reflection configuration, JNI access control, and lifecycle management. These APIs control what gets included in the final executable during the compilation phase.

3

4

## Capabilities

5

6

### Feature System

7

8

Comprehensive lifecycle hooks for customizing native image generation through well-defined phases.

9

10

```java { .api }

11

/**

12

* Interface for intercepting and customizing native image generation

13

*/

14

interface Feature {

15

/** Check if this feature should be included in the configuration */

16

default boolean isInConfiguration(IsInConfigurationAccess access) {

17

return true;

18

}

19

20

/** Called before analysis phase begins */

21

default void beforeAnalysis(BeforeAnalysisAccess access) {}

22

23

/** Called during analysis phase for iterative processing */

24

default void duringAnalysis(DuringAnalysisAccess access) {}

25

26

/** Called after analysis phase completes */

27

default void afterAnalysis(AfterAnalysisAccess access) {}

28

29

/** Called before compilation phase begins */

30

default void beforeCompilation(BeforeCompilationAccess access) {}

31

32

/** Called after heap layout is determined */

33

default void afterHeapLayout(AfterHeapLayoutAccess access) {}

34

35

/** Called before image writing */

36

default void beforeImageWrite(BeforeImageWriteAccess access) {}

37

38

/** Called after image generation completes */

39

default void afterImageWrite(AfterImageWriteAccess access) {}

40

41

/** Called when feature causes analysis iteration */

42

default void onAnalysisExit(OnAnalysisExitAccess access) {}

43

}

44

45

/**

46

* Access interface for configuration checking

47

*/

48

interface IsInConfigurationAccess {

49

/** Find optional class by name */

50

Class<?> findClassByName(String className);

51

52

/** Get application class loader */

53

ClassLoader getApplicationClassLoader();

54

}

55

56

/**

57

* Access interface for before analysis phase

58

*/

59

interface BeforeAnalysisAccess {

60

/** Register class as reachable */

61

void registerAsReachable(Class<?> clazz);

62

63

/** Register field as accessed */

64

void registerAsAccessed(Field field);

65

66

/** Register method as reachable */

67

void registerAsReachable(Method method);

68

69

/** Register constructor as reachable */

70

void registerAsReachable(Constructor<?> constructor);

71

72

/** Register for reflection */

73

void registerForReflectiveInstantiation(Class<?> clazz);

74

}

75

76

/**

77

* Access interface for during analysis phase

78

*/

79

interface DuringAnalysisAccess extends BeforeAnalysisAccess {

80

/** Check if analysis needs to be repeated */

81

boolean requireAnalysisIteration();

82

83

/** Get reachable classes */

84

Set<Class<?>> getReachableClasses();

85

86

/** Get reachable methods */

87

Set<Method> getReachableMethods();

88

}

89

```

90

91

**Usage Examples:**

92

93

```java

94

// Custom feature implementation

95

public class MyCustomFeature implements Feature {

96

@Override

97

public void beforeAnalysis(BeforeAnalysisAccess access) {

98

// Register classes for analysis

99

access.registerAsReachable(MyImportantClass.class);

100

access.registerForReflectiveInstantiation(MyReflectedClass.class);

101

}

102

103

@Override

104

public void duringAnalysis(DuringAnalysisAccess access) {

105

// Iterative processing during analysis

106

Set<Class<?>> reachable = access.getReachableClasses();

107

for (Class<?> clazz : reachable) {

108

if (needsSpecialHandling(clazz)) {

109

registerSpecialMethods(clazz, access);

110

access.requireAnalysisIteration();

111

}

112

}

113

}

114

115

@Override

116

public void afterAnalysis(AfterAnalysisAccess access) {

117

// Final processing after analysis

118

System.out.println("Analysis complete, proceeding to compilation");

119

}

120

}

121

122

// Register the feature

123

// (typically done via META-INF/services/org.graalvm.nativeimage.hosted.Feature)

124

```

125

126

### Runtime Reflection Configuration

127

128

Register classes, methods, and fields for runtime reflection access.

129

130

```java { .api }

131

/**

132

* Configuration API for runtime reflection access

133

*/

134

class RuntimeReflection {

135

/** Register classes for runtime reflection */

136

static void register(Class<?>... classes);

137

138

/** Register constructors for runtime reflection */

139

static void register(Constructor<?>... constructors);

140

141

/** Register methods for runtime reflection */

142

static void register(Method... methods);

143

144

/** Register fields for runtime reflection */

145

static void register(Field... fields);

146

147

/** Register all declared constructors of classes */

148

static void registerAllDeclaredConstructors(Class<?>... classes);

149

150

/** Register all declared methods of classes */

151

static void registerAllDeclaredMethods(Class<?>... classes);

152

153

/** Register all declared fields of classes */

154

static void registerAllDeclaredFields(Class<?>... classes);

155

156

/** Register classes for reflective instantiation */

157

static void registerForReflectiveInstantiation(Class<?>... classes);

158

}

159

```

160

161

**Usage Examples:**

162

163

```java

164

// Register specific elements

165

RuntimeReflection.register(MyClass.class);

166

RuntimeReflection.register(MyClass.class.getDeclaredMethod("myMethod"));

167

RuntimeReflection.register(MyClass.class.getDeclaredField("myField"));

168

169

// Register all elements of a class

170

RuntimeReflection.registerAllDeclaredMethods(MyClass.class);

171

RuntimeReflection.registerAllDeclaredFields(MyClass.class);

172

173

// Register for instantiation

174

RuntimeReflection.registerForReflectiveInstantiation(MyClass.class);

175

176

// In a Feature

177

public class ReflectionFeature implements Feature {

178

@Override

179

public void beforeAnalysis(BeforeAnalysisAccess access) {

180

// Bulk registration

181

RuntimeReflection.register(

182

String.class,

183

List.class,

184

Map.class

185

);

186

187

// Dynamic registration based on classpath scanning

188

registerJsonClasses();

189

}

190

191

private void registerJsonClasses() {

192

// Find and register classes with JSON annotations

193

for (Class<?> clazz : findClassesWithAnnotation(JsonSerializable.class)) {

194

RuntimeReflection.registerAllDeclaredFields(clazz);

195

RuntimeReflection.registerAllDeclaredConstructors(clazz);

196

}

197

}

198

}

199

```

200

201

### JNI Access Configuration

202

203

Configure JNI access for runtime native method calls.

204

205

```java { .api }

206

/**

207

* Configuration API for runtime JNI access

208

*/

209

class RuntimeJNIAccess {

210

/** Register classes for JNI access */

211

static void register(Class<?>... classes);

212

213

/** Register constructors for JNI access */

214

static void register(Constructor<?>... constructors);

215

216

/** Register methods for JNI access */

217

static void register(Method... methods);

218

219

/** Register fields for JNI access */

220

static void register(Field... fields);

221

222

/** Register all declared constructors for JNI */

223

static void registerAllDeclaredConstructors(Class<?>... classes);

224

225

/** Register all declared methods for JNI */

226

static void registerAllDeclaredMethods(Class<?>... classes);

227

228

/** Register all declared fields for JNI */

229

static void registerAllDeclaredFields(Class<?>... classes);

230

}

231

```

232

233

**Usage Examples:**

234

235

```java

236

// Register JNI-accessible elements

237

RuntimeJNIAccess.register(NativeInterface.class);

238

RuntimeJNIAccess.register(

239

NativeInterface.class.getDeclaredMethod("nativeCallback", int.class)

240

);

241

242

// Register all JNI methods

243

RuntimeJNIAccess.registerAllDeclaredMethods(JNIHelper.class);

244

245

// In a Feature for JNI libraries

246

public class JNIFeature implements Feature {

247

@Override

248

public void beforeAnalysis(BeforeAnalysisAccess access) {

249

// Register classes used by native libraries

250

RuntimeJNIAccess.register(

251

CallbackHandler.class,

252

DataProcessor.class,

253

ErrorReporter.class

254

);

255

256

// Register specific methods called from native code

257

try {

258

Method callback = CallbackHandler.class.getDeclaredMethod("onEvent", String.class);

259

RuntimeJNIAccess.register(callback);

260

} catch (NoSuchMethodException e) {

261

throw new RuntimeException(e);

262

}

263

}

264

}

265

```

266

267

### Class Initialization Configuration

268

269

Control when classes are initialized during build time vs runtime.

270

271

```java { .api }

272

/**

273

* Configuration API for controlling class initialization timing

274

*/

275

class RuntimeClassInitialization {

276

/** Initialize classes at build time */

277

static void initializeAtBuildTime(Class<?>... classes);

278

279

/** Initialize classes at build time by name */

280

static void initializeAtBuildTime(String... classNames);

281

282

/** Initialize classes at runtime */

283

static void initializeAtRunTime(Class<?>... classes);

284

285

/** Initialize classes at runtime by name */

286

static void initializeAtRunTime(String... classNames);

287

288

/** Initialize packages at build time */

289

static void initializeAtBuildTimePackage(String... packageNames);

290

291

/** Initialize packages at runtime */

292

static void initializeAtRunTimePackage(String... packageNames);

293

}

294

```

295

296

**Usage Examples:**

297

298

```java

299

// Build-time initialization for constants and utilities

300

RuntimeClassInitialization.initializeAtBuildTime(

301

Constants.class,

302

UtilityClass.class,

303

"com.example.config"

304

);

305

306

// Runtime initialization for stateful classes

307

RuntimeClassInitialization.initializeAtRunTime(

308

DatabaseConnection.class,

309

ThreadPool.class,

310

"com.example.runtime"

311

);

312

313

// Package-level control

314

RuntimeClassInitialization.initializeAtBuildTimePackage("com.example.constants");

315

RuntimeClassInitialization.initializeAtRunTimePackage("com.example.services");

316

317

// In a Feature

318

public class InitializationFeature implements Feature {

319

@Override

320

public void beforeAnalysis(BeforeAnalysisAccess access) {

321

// Configure based on application needs

322

configureLogging();

323

configureDatabase();

324

}

325

326

private void configureLogging() {

327

// Logging can be initialized at build time

328

RuntimeClassInitialization.initializeAtBuildTime(

329

"org.slf4j",

330

"ch.qos.logback.classic",

331

"ch.qos.logback.core"

332

);

333

}

334

335

private void configureDatabase() {

336

// Database connections must be runtime

337

RuntimeClassInitialization.initializeAtRunTime(

338

"javax.sql",

339

"com.zaxxer.hikari"

340

);

341

}

342

}

343

```

344

345

### Additional Configuration APIs

346

347

Other build-time configuration capabilities.

348

349

```java { .api }

350

/**

351

* Configuration API for dynamic proxy creation

352

*/

353

class RuntimeProxyCreation {

354

/** Register interfaces for dynamic proxy creation */

355

static void register(Class<?>... interfaces);

356

}

357

358

/**

359

* Configuration API for serialization support

360

*/

361

class RuntimeSerialization {

362

/** Register classes for serialization */

363

static void register(Class<?>... classes);

364

365

/** Register classes for serialization by name */

366

static void register(String... classNames);

367

}

368

369

/**

370

* Configuration API for resource access

371

*/

372

class RuntimeResourceAccess {

373

/** Register resources for runtime access */

374

static void addResource(String resource);

375

376

/** Register resource bundles */

377

static void addResourceBundle(String bundleName);

378

379

/** Register resource patterns */

380

static void addResourcePattern(String pattern);

381

}

382

383

/**

384

* Configuration API for system properties

385

*/

386

class RuntimeSystemProperties {

387

/** Set system property for runtime */

388

static void set(String key, String value);

389

390

/** Register system property for access */

391

static void register(String key);

392

}

393

394

/**

395

* Configuration API for foreign function access

396

*/

397

class RuntimeForeignAccess {

398

/** Register foreign functions for runtime access */

399

static void register(String... functions);

400

}

401

402

/**

403

* Transform field values during image building

404

*/

405

interface FieldValueTransformer {

406

/** Transform field value during build */

407

Object transform(Field field, Object receiver, Object value);

408

}

409

```

410

411

**Usage Examples:**

412

413

```java

414

// Proxy configuration

415

RuntimeProxyCreation.register(MyInterface.class, AnotherInterface.class);

416

417

// Serialization support

418

RuntimeSerialization.register(

419

MySerializableClass.class,

420

"com.example.data.UserData",

421

"com.example.data.Configuration"

422

);

423

424

// Resource access

425

RuntimeResourceAccess.addResource("config.properties");

426

RuntimeResourceAccess.addResourceBundle("messages");

427

RuntimeResourceAccess.addResourcePattern("static/.*\\.html");

428

429

// System properties

430

RuntimeSystemProperties.set("app.version", "1.0.0");

431

RuntimeSystemProperties.register("user.home");

432

433

// Foreign function access

434

RuntimeForeignAccess.register("malloc", "free", "strlen");

435

436

// Field transformation

437

public class ConfigTransformer implements FieldValueTransformer {

438

@Override

439

public Object transform(Field field, Object receiver, Object value) {

440

if (field.getName().equals("databaseUrl")) {

441

// Transform database URL at build time

442

return processConfigValue((String) value);

443

}

444

return value;

445

}

446

}

447

```

448

449

### Complete Feature Example

450

451

```java

452

/**

453

* Comprehensive feature demonstrating multiple configuration aspects

454

*/

455

public class ApplicationFeature implements Feature {

456

@Override

457

public void beforeAnalysis(BeforeAnalysisAccess access) {

458

configureReflection();

459

configureJNI();

460

configureInitialization();

461

configureResources();

462

configureSerialization();

463

}

464

465

private void configureReflection() {

466

// Register framework classes

467

RuntimeReflection.register(

468

MyController.class,

469

MyService.class,

470

MyRepository.class

471

);

472

473

// Register annotation-driven components

474

for (Class<?> clazz : findAnnotatedClasses(Component.class)) {

475

RuntimeReflection.registerAllDeclaredMethods(clazz);

476

RuntimeReflection.registerForReflectiveInstantiation(clazz);

477

}

478

}

479

480

private void configureJNI() {

481

// Register native method classes

482

RuntimeJNIAccess.register(NativeLibrary.class);

483

RuntimeJNIAccess.registerAllDeclaredMethods(JNICallback.class);

484

}

485

486

private void configureInitialization() {

487

// Build-time initialization for constants

488

RuntimeClassInitialization.initializeAtBuildTime(

489

"com.example.constants",

490

"com.example.config"

491

);

492

493

// Runtime initialization for stateful components

494

RuntimeClassInitialization.initializeAtRunTime(

495

"com.example.database",

496

"com.example.network"

497

);

498

}

499

500

private void configureResources() {

501

// Application resources

502

RuntimeResourceAccess.addResource("application.properties");

503

RuntimeResourceAccess.addResourcePattern("templates/.*");

504

RuntimeResourceAccess.addResourceBundle("messages");

505

}

506

507

private void configureSerialization() {

508

// DTO classes for JSON serialization

509

for (Class<?> dto : findDTOClasses()) {

510

RuntimeSerialization.register(dto);

511

RuntimeReflection.registerAllDeclaredFields(dto);

512

}

513

}

514

515

@Override

516

public void duringAnalysis(DuringAnalysisAccess access) {

517

// Dynamic registration based on analysis results

518

boolean hasNewReachableClasses = false;

519

520

for (Class<?> clazz : access.getReachableClasses()) {

521

if (isFrameworkClass(clazz)) {

522

registerFrameworkRequirements(clazz, access);

523

hasNewReachableClasses = true;

524

}

525

}

526

527

if (hasNewReachableClasses) {

528

access.requireAnalysisIteration();

529

}

530

}

531

532

@Override

533

public void afterAnalysis(AfterAnalysisAccess access) {

534

// Validation and final setup

535

validateConfiguration();

536

generateBuildReport();

537

}

538

}

539

```

540

541

This build-time configuration system provides comprehensive control over native image generation, enabling applications to precisely specify what functionality should be available at runtime while optimizing the final executable size and performance.