0
# Runtime Core APIs
1
2
Core runtime functionality for native image execution, including isolate management, memory allocation, threading support, platform abstraction, and execution context information.
3
4
## Capabilities
5
6
### Execution Context Information
7
8
Query the current execution context to determine whether code is running during native image build time or at runtime.
9
10
```java { .api }
11
/**
12
* Utility class providing information about the current execution context
13
*/
14
class ImageInfo {
15
/** Returns true if executing during native image generation */
16
static boolean inImageBuildtimeCode();
17
18
/** Returns true if executing in a native image at runtime */
19
static boolean inImageRuntimeCode();
20
21
/** Returns true if executing in any image context (build or runtime) */
22
static boolean inImageCode();
23
24
/** Returns true if the current executable is a native executable */
25
static boolean isExecutable();
26
27
/** Returns true if the current executable is a shared library */
28
static boolean isSharedLibrary();
29
}
30
```
31
32
**Usage Examples:**
33
34
```java
35
// Conditional behavior based on execution context
36
if (ImageInfo.inImageBuildtimeCode()) {
37
// Expensive initialization only during build
38
precomputeConstants();
39
} else if (ImageInfo.inImageRuntimeCode()) {
40
// Runtime-specific optimizations
41
enableFastPaths();
42
}
43
44
// Check executable type
45
if (ImageInfo.isSharedLibrary()) {
46
// Library-specific initialization
47
registerCallbacks();
48
}
49
```
50
51
### Platform Abstraction
52
53
Comprehensive platform support with conditional compilation capabilities.
54
55
```java { .api }
56
/**
57
* Root interface for all platform types
58
*/
59
interface Platform {}
60
61
/**
62
* Annotation to restrict code to specific platforms
63
*/
64
@interface Platforms {
65
Class<? extends Platform>[] value();
66
}
67
68
// Architecture platforms
69
interface AMD64 extends Platform {}
70
interface AARCH64 extends Platform {}
71
interface RISCV64 extends Platform {}
72
73
// Operating system platforms
74
interface LINUX extends Platform {}
75
interface ANDROID extends LINUX {}
76
interface DARWIN extends Platform {}
77
interface IOS extends DARWIN {}
78
interface MACOS extends DARWIN {}
79
interface WINDOWS extends Platform {}
80
81
// Base combinations
82
interface LINUX_AMD64_BASE extends LINUX, AMD64 {}
83
interface LINUX_AARCH64_BASE extends LINUX, AARCH64 {}
84
interface DARWIN_AMD64 extends DARWIN, AMD64 {}
85
interface DARWIN_AARCH64 extends DARWIN, AARCH64 {}
86
87
// Leaf platforms (concrete implementations)
88
class LINUX_AMD64 implements LINUX, LINUX_AMD64_BASE {}
89
class LINUX_AARCH64 implements LINUX, LINUX_AARCH64_BASE {}
90
class LINUX_RISCV64 implements LINUX, RISCV64 {}
91
class ANDROID_AARCH64 implements ANDROID, LINUX_AARCH64_BASE {}
92
class IOS_AMD64 implements IOS, DARWIN_AMD64 {}
93
class IOS_AARCH64 implements IOS, DARWIN_AARCH64 {}
94
class MACOS_AMD64 implements MACOS, DARWIN_AMD64 {}
95
class MACOS_AARCH64 implements MACOS, DARWIN_AARCH64 {}
96
class WINDOWS_AMD64 implements WINDOWS, AMD64 {}
97
class WINDOWS_AARCH64 implements WINDOWS, AARCH64 {}
98
99
// Special marker platform
100
class HOSTED_ONLY implements Platform {} // Build-time only
101
```
102
103
**Usage Examples:**
104
105
```java
106
// Platform-specific code
107
@Platforms({Platform.LINUX.class, Platform.DARWIN.class})
108
public class UnixSpecificCode {
109
public void doUnixStuff() {
110
// Only compiled on Unix-like platforms (Linux, Android, macOS, iOS)
111
}
112
}
113
114
// Mobile-specific code
115
@Platforms({Platform.ANDROID_AARCH64.class, Platform.IOS_AARCH64.class})
116
public class MobileOptimizations {
117
public void optimizeForMobile() {
118
// Mobile-specific implementations
119
}
120
}
121
122
// Runtime platform checks
123
if (Platform.includedIn(Platform.LINUX.class)) {
124
// Linux-specific runtime behavior (includes Android)
125
}
126
127
if (Platform.includedIn(Platform.ANDROID.class)) {
128
// Android-specific behavior
129
}
130
131
if (Platform.includedIn(Platform.MACOS.class)) {
132
// macOS-specific behavior
133
}
134
135
if (Platform.includedIn(Platform.IOS.class)) {
136
// iOS-specific behavior
137
}
138
139
// Architecture-specific optimizations
140
@Platforms(Platform.AMD64.class)
141
public void optimizedForAMD64() {
142
// AMD64-specific implementation (Intel/AMD 64-bit)
143
}
144
145
@Platforms(Platform.AARCH64.class)
146
public void optimizedForARM64() {
147
// ARM64-specific implementation (Apple Silicon, ARM servers)
148
}
149
150
@Platforms(Platform.RISCV64.class)
151
public void optimizedForRISCV() {
152
// RISC-V 64-bit specific implementation
153
}
154
155
// Specific platform combinations
156
@Platforms(Platform.WINDOWS_AARCH64.class)
157
public void windowsARM64Specific() {
158
// Windows on ARM64 (Surface Pro X, etc.)
159
}
160
161
@Platforms({Platform.MACOS_AARCH64.class, Platform.IOS_AARCH64.class})
162
public void appleARM64Optimizations() {
163
// Optimizations for Apple Silicon (M1/M2/M3)
164
}
165
166
// Build-time only code
167
@Platforms(Platform.HOSTED_ONLY.class)
168
public class BuildTimeUtilities {
169
// Only available during native image generation
170
}
171
```
172
173
### Singleton Registry
174
175
Key-value store for compile-time constant lookup and configuration sharing.
176
177
```java { .api }
178
/**
179
* Registry for singleton objects available during native image generation
180
*/
181
class ImageSingletons {
182
/** Store a singleton instance for the given key class */
183
static <T> void add(Class<T> key, T value);
184
185
/** Retrieve the singleton instance for the given key class */
186
static <T> T lookup(Class<T> key);
187
188
/** Check if a singleton is registered for the given key class */
189
static boolean contains(Class<?> key);
190
}
191
```
192
193
**Usage Examples:**
194
195
```java
196
// Register configuration during build
197
ImageSingletons.add(MyConfig.class, new MyConfig());
198
199
// Lookup configuration at runtime
200
MyConfig config = ImageSingletons.lookup(MyConfig.class);
201
202
// Conditional access
203
if (ImageSingletons.contains(OptionalFeature.class)) {
204
OptionalFeature feature = ImageSingletons.lookup(OptionalFeature.class);
205
feature.enable();
206
}
207
```
208
209
### Isolate Management
210
211
Multi-isolate support with independent memory spaces and cross-isolate communication.
212
213
```java { .api }
214
/**
215
* Pointer to an isolate's runtime data structure
216
*/
217
interface Isolate extends PointerBase {}
218
219
/**
220
* Pointer to thread-specific data within an isolate
221
*/
222
interface IsolateThread extends PointerBase {}
223
224
/**
225
* Support for isolate creation, access, and management
226
*/
227
class Isolates {
228
/** Create a new isolate with specified parameters */
229
static IsolateThread createIsolate(CreateIsolateParameters params) throws IsolateException;
230
231
/** Attach the current thread to an existing isolate */
232
static IsolateThread attachCurrentThread(Isolate isolate) throws IsolateException;
233
234
/** Get current thread's structure for the specified isolate */
235
static IsolateThread getCurrentThread(Isolate isolate) throws IsolateException;
236
237
/** Get the isolate of a thread */
238
static Isolate getIsolate(IsolateThread thread) throws IsolateException;
239
240
/** Detach a thread from its isolate */
241
static void detachThread(IsolateThread thread) throws IsolateException;
242
243
/** Tear down an isolate and all its threads */
244
static void tearDownIsolate(IsolateThread thread) throws IsolateException;
245
246
/** Exception thrown during isolate operations */
247
static class IsolateException extends RuntimeException {
248
IsolateException(String message);
249
}
250
}
251
252
/**
253
* Parameters for isolate creation with builder pattern
254
*/
255
class CreateIsolateParameters {
256
/** Get default isolate creation parameters */
257
static CreateIsolateParameters getDefault();
258
259
/** Get reserved address space size */
260
UnsignedWord getReservedAddressSpaceSize();
261
262
/** Get auxiliary image path */
263
String getAuxiliaryImagePath();
264
265
/** Get auxiliary image reserved space size */
266
UnsignedWord getAuxiliaryImageReservedSpaceSize();
267
268
/** Get additional isolate arguments */
269
List<String> getArguments();
270
271
/** Get memory protection domain */
272
ProtectionDomain getProtectionDomain();
273
274
/** Builder for CreateIsolateParameters */
275
static class Builder {
276
Builder();
277
278
/** Set reserved virtual address space size */
279
Builder reservedAddressSpaceSize(UnsignedWord size);
280
281
/** Set auxiliary image file path */
282
Builder auxiliaryImagePath(String filePath);
283
284
/** Set auxiliary image reserved space size */
285
Builder auxiliaryImageReservedSpaceSize(UnsignedWord size);
286
287
/** Append isolate argument (Native Image syntax) */
288
Builder appendArgument(String argument);
289
290
/** Set memory protection domain */
291
Builder setProtectionDomain(ProtectionDomain domain);
292
293
/** Build the final parameters */
294
CreateIsolateParameters build();
295
}
296
}
297
298
/**
299
* Memory protection domain for isolates
300
*/
301
interface ProtectionDomain {
302
/** Singleton: no protection domain */
303
ProtectionDomain NO_DOMAIN = /* implementation */;
304
305
/** Singleton: create new protection domain */
306
ProtectionDomain NEW_DOMAIN = /* implementation */;
307
}
308
309
/**
310
* Utilities for accessing the current isolate
311
*/
312
class CurrentIsolate {
313
/** Get the current thread's IsolateThread pointer */
314
static IsolateThread getCurrentThread();
315
316
/** Get the current isolate */
317
static Isolate getIsolate();
318
}
319
```
320
321
**Usage Examples:**
322
323
```java
324
// Create a new isolate with custom parameters
325
CreateIsolateParameters params = new CreateIsolateParameters.Builder()
326
.reservedAddressSpaceSize(WordFactory.unsigned(1024 * 1024 * 1024)) // 1GB
327
.auxiliaryImagePath("/path/to/auxiliary.so")
328
.appendArgument("-XX:+AutomaticReferenceHandling")
329
.appendArgument("-XX:MaxRAMPercentage=50")
330
.setProtectionDomain(ProtectionDomain.NEW_DOMAIN)
331
.build();
332
333
try {
334
IsolateThread newIsolateThread = Isolates.createIsolate(params);
335
System.out.println("Created isolate with thread: " + newIsolateThread);
336
} catch (Isolates.IsolateException e) {
337
System.err.println("Failed to create isolate: " + e.getMessage());
338
}
339
340
// Work with current isolate
341
IsolateThread currentThread = CurrentIsolate.getCurrentThread();
342
Isolate currentIsolate = CurrentIsolate.getIsolate();
343
344
// Cross-isolate operations with error handling
345
try {
346
Isolate targetIsolate = Isolates.getIsolate(someThread);
347
IsolateThread attachedThread = Isolates.attachCurrentThread(targetIsolate);
348
349
// Do work in the attached isolate
350
performWork();
351
352
// Clean up
353
Isolates.detachThread(attachedThread);
354
} catch (Isolates.IsolateException e) {
355
System.err.println("Isolate operation failed: " + e.getMessage());
356
}
357
358
// Complete isolate lifecycle
359
try {
360
// Create isolate with default parameters
361
IsolateThread isolateThread = Isolates.createIsolate(CreateIsolateParameters.getDefault());
362
363
// Get the isolate handle
364
Isolate isolate = Isolates.getIsolate(isolateThread);
365
366
// Attach another thread
367
IsolateThread secondThread = Isolates.attachCurrentThread(isolate);
368
369
// Detach the second thread
370
Isolates.detachThread(secondThread);
371
372
// Tear down the entire isolate
373
Isolates.tearDownIsolate(isolateThread);
374
} catch (Isolates.IsolateException e) {
375
System.err.println("Isolate lifecycle error: " + e.getMessage());
376
}
377
```
378
379
### Memory Management
380
381
Stack allocation, unmanaged memory operations, and pinned objects for native interop.
382
383
```java { .api }
384
/**
385
* Stack frame memory allocation utilities
386
*/
387
class StackValue {
388
/** Allocate memory on the stack for the given type */
389
static <T extends PointerBase> T get(Class<T> structType);
390
391
/** Allocate an array on the stack */
392
static <T extends PointerBase> T get(int length, Class<T> elementType);
393
394
/** Allocate memory of specific size on the stack */
395
static <T extends PointerBase> T get(int sizeInBytes);
396
}
397
398
/**
399
* malloc/free-style unmanaged memory operations
400
*/
401
class UnmanagedMemory {
402
/** Allocate unmanaged memory */
403
static <T extends PointerBase> T malloc(int sizeInBytes);
404
405
/** Reallocate unmanaged memory */
406
static <T extends PointerBase> T realloc(T ptr, int newSizeInBytes);
407
408
/** Free unmanaged memory */
409
static void free(PointerBase ptr);
410
411
/** Copy memory between locations */
412
static void copy(PointerBase from, PointerBase to, int sizeInBytes);
413
}
414
415
/**
416
* Holder for pinned objects with AutoCloseable support
417
*/
418
class PinnedObject implements AutoCloseable {
419
/** Create a pinned object from an array */
420
static PinnedObject create(Object object);
421
422
/** Get pointer to the start of the pinned object */
423
<T extends PointerBase> T addressOfArrayElement(int index);
424
425
/** Release the pinned object */
426
void close();
427
}
428
```
429
430
**Usage Examples:**
431
432
```java
433
// Stack allocation
434
CIntPointer stackInt = StackValue.get(CIntPointer.class);
435
stackInt.write(42);
436
437
// Array on stack
438
CIntPointer stackArray = StackValue.get(10, CIntPointer.class);
439
for (int i = 0; i < 10; i++) {
440
stackArray.addressOf(i).write(i);
441
}
442
443
// Unmanaged memory
444
CCharPointer buffer = UnmanagedMemory.malloc(1024);
445
try {
446
// Use buffer...
447
} finally {
448
UnmanagedMemory.free(buffer);
449
}
450
451
// Pinned objects for native interop
452
byte[] javaArray = new byte[100];
453
try (PinnedObject pinned = PinnedObject.create(javaArray)) {
454
CCharPointer nativePtr = pinned.addressOfArrayElement(0);
455
// Pass nativePtr to native functions
456
}
457
```
458
459
### Object Handles
460
461
Cross-isolate communication via opaque object references.
462
463
```java { .api }
464
/**
465
* Opaque representation of handles to Java objects
466
*/
467
interface ObjectHandle extends PointerBase {}
468
469
/**
470
* Management of ObjectHandle sets with global and local scopes
471
*/
472
class ObjectHandles {
473
/** Get the global object handles */
474
static ObjectHandles getGlobal();
475
476
/** Create a new local object handle set */
477
static ObjectHandles create();
478
479
/** Create a handle for the given object */
480
ObjectHandle create(Object object);
481
482
/** Get the object for the given handle */
483
<T> T get(ObjectHandle handle);
484
485
/** Destroy a handle */
486
void destroy(ObjectHandle handle);
487
488
/** Destroy all handles in this set */
489
void destroyAll();
490
}
491
```
492
493
**Usage Examples:**
494
495
```java
496
// Global handles (persist across calls)
497
ObjectHandles global = ObjectHandles.getGlobal();
498
ObjectHandle handle = global.create(myObject);
499
500
// Local handles (cleaned up automatically)
501
ObjectHandles local = ObjectHandles.create();
502
ObjectHandle localHandle = local.create(localObject);
503
504
// Cross-isolate communication
505
String retrieved = global.get(handle);
506
```
507
508
### Threading and Runtime Support
509
510
Thread management, callback registration, and VM lifecycle control.
511
512
```java { .api }
513
/**
514
* Thread management and callback registration
515
*/
516
class Threading {
517
/** Register a recurring callback */
518
static void registerRecurringCallback(long intervalNanos, Runnable callback);
519
520
/** Check if called from a thread that was attached externally */
521
static boolean isCurrentThreadVirtual();
522
}
523
524
/**
525
* VM initialization, shutdown, and diagnostic operations
526
*/
527
class VMRuntime {
528
/** Initialize the VM runtime */
529
static void initialize();
530
531
/** Shut down the VM */
532
static void shutdown();
533
534
/** Dump the heap to a file */
535
static void dumpHeap(String outputFile, boolean live);
536
}
537
538
/**
539
* Access to runtime options and configuration
540
*/
541
class RuntimeOptions {
542
/** Get a runtime option value */
543
static <T> T get(String optionName);
544
545
/** Set a runtime option value */
546
static <T> void set(String optionName, T value);
547
}
548
```
549
550
**Usage Examples:**
551
552
```java
553
// Recurring callbacks
554
Threading.registerRecurringCallback(1_000_000_000L, () -> {
555
System.out.println("Heartbeat");
556
});
557
558
// VM lifecycle
559
VMRuntime.initialize();
560
try {
561
// Application logic
562
} finally {
563
VMRuntime.shutdown();
564
}
565
566
// Heap diagnostics
567
VMRuntime.dumpHeap("/tmp/heap.hprof", true);
568
569
// Runtime options
570
String gcType = RuntimeOptions.get("gc.type");
571
RuntimeOptions.set("debug.enabled", true);
572
```
573
574
### Utility APIs
575
576
Additional utilities for annotation access, process properties, and logging.
577
578
```java { .api }
579
/**
580
* Runtime annotation access utilities
581
*/
582
class AnnotationAccess {
583
/** Check if annotation is present on element */
584
static boolean isAnnotationPresent(AnnotatedElement element, Class<? extends Annotation> annotation);
585
586
/** Get annotation from element */
587
static <T extends Annotation> T getAnnotation(AnnotatedElement element, Class<T> annotation);
588
}
589
590
/**
591
* Process property access
592
*/
593
class ProcessProperties {
594
/** Get process ID */
595
static long getProcessID();
596
597
/** Get executable path */
598
static String getExecutableName();
599
600
/** Get command line arguments */
601
static String[] getArgumentVector();
602
}
603
604
/**
605
* Custom logging support
606
*/
607
interface LogHandler {
608
/** Handle a log message */
609
void log(String message);
610
}
611
```
612
613
### Error Handling
614
615
Exception classes for diagnosing and handling registration-related errors in native images.
616
617
```java { .api }
618
/**
619
* Exception thrown when reflection queries access unregistered elements
620
*/
621
class MissingReflectionRegistrationError extends Error {
622
/** Constructor with detailed information about the missing element */
623
MissingReflectionRegistrationError(String message, Class<?> elementType,
624
Class<?> declaringClass, String elementName,
625
Class<?>[] parameterTypes);
626
627
/** Get the type of element being queried (Class, Method, Field, Constructor) */
628
Class<?> getElementType();
629
630
/** Get the class on which the query was attempted */
631
Class<?> getDeclaringClass();
632
633
/** Get the name of the queried element or bulk query method */
634
String getElementName();
635
636
/** Get parameter types passed to the query */
637
Class<?>[] getParameterTypes();
638
}
639
640
/**
641
* Exception thrown when JNI queries access unregistered elements
642
*/
643
class MissingJNIRegistrationError extends Error {
644
/** Constructor with detailed information about the missing JNI element */
645
MissingJNIRegistrationError(String message, Class<?> elementType,
646
Class<?> declaringClass, String elementName,
647
String signature);
648
649
/** Get the type of element being queried (Class, Method, Field, Constructor) */
650
Class<?> getElementType();
651
652
/** Get the class on which the query was attempted */
653
Class<?> getDeclaringClass();
654
655
/** Get the name of the queried element */
656
String getElementName();
657
658
/** Get the JNI signature passed to the query */
659
String getSignature();
660
}
661
```
662
663
**Usage Examples:**
664
665
```java
666
// Handling reflection registration errors
667
try {
668
Method method = MyClass.class.getDeclaredMethod("unregisteredMethod");
669
} catch (MissingReflectionRegistrationError e) {
670
System.err.println("Missing reflection registration: " +
671
e.getElementName() + " in " + e.getDeclaringClass());
672
// Log for build-time registration
673
registerForNextBuild(e.getDeclaringClass(), e.getElementName());
674
}
675
676
// Handling JNI registration errors
677
try {
678
// JNI call that triggers registration check
679
nativeMethodCall();
680
} catch (MissingJNIRegistrationError e) {
681
System.err.println("Missing JNI registration: " +
682
e.getElementName() + " with signature " + e.getSignature());
683
// Handle gracefully or fail fast
684
}
685
686
// Prevention: Register elements at build time
687
// In a Feature class:
688
RuntimeReflection.register(MyClass.class.getDeclaredMethod("methodName"));
689
RuntimeJNIAccess.register(MyClass.class);
690
```
691
692
These runtime core APIs provide the foundation for native image execution, enabling applications to manage memory, communicate across isolates, handle platform differences, and control runtime behavior while maintaining the performance benefits of ahead-of-time compilation.