0
# Engine and Language Management
1
2
Engine and language management provide comprehensive control over the GraalVM runtime environment, language discovery, and shared resources. The Engine serves as the foundation for multiple contexts while Language objects provide metadata and capabilities for installed language implementations.
3
4
## Capabilities
5
6
### Engine Creation and Configuration
7
8
Create and configure shared runtime engines for optimal performance and resource management.
9
10
```java { .api }
11
/**
12
* Creates a new engine with default configuration
13
* @return new Engine instance
14
*/
15
public static Engine create();
16
17
/**
18
* Creates a builder for advanced engine configuration
19
* @return Engine.Builder for fluent configuration
20
*/
21
public static Builder newBuilder();
22
23
/**
24
* Gets the installed languages available in this engine
25
* @return Map of language ID to Language objects
26
*/
27
public Map<String, Language> getLanguages();
28
29
/**
30
* Gets the installed instruments available in this engine
31
* @return Map of instrument ID to Instrument objects
32
*/
33
public Map<String, Instrument> getInstruments();
34
35
/**
36
* Gets the engine version string
37
* @return version information
38
*/
39
public String getVersion();
40
41
/**
42
* Closes the engine and releases all resources
43
* Waits for any currently executing contexts to complete
44
*/
45
public void close();
46
47
/**
48
* Closes the engine with optional cancellation of executing contexts
49
* @param cancelIfExecuting if true, cancels any currently executing contexts
50
*/
51
public void close(boolean cancelIfExecuting);
52
53
/**
54
* Checks if the engine has been closed
55
* @return true if the engine is closed
56
*/
57
public boolean isClosed();
58
```
59
60
**Usage Examples:**
61
62
```java
63
// Simple engine creation
64
Engine engine = Engine.create();
65
66
// Check available languages
67
Map<String, Language> languages = engine.getLanguages();
68
if (languages.containsKey("python")) {
69
Language python = languages.get("python");
70
System.out.println("Python available: " + python.getName() + " v" + python.getVersion());
71
}
72
73
// List all available languages
74
System.out.println("Available languages:");
75
for (Map.Entry<String, Language> entry : languages.entrySet()) {
76
Language lang = entry.getValue();
77
System.out.println("- " + entry.getKey() + ": " + lang.getName() + " v" + lang.getVersion());
78
}
79
80
// Check instruments
81
Map<String, Instrument> instruments = engine.getInstruments();
82
System.out.println("Available instruments: " + instruments.keySet());
83
84
// Engine lifecycle management
85
try (Engine sharedEngine = Engine.create()) {
86
// Create multiple contexts sharing the same engine
87
try (Context context1 = Context.newBuilder("python").engine(sharedEngine).build();
88
Context context2 = Context.newBuilder("python").engine(sharedEngine).build()) {
89
90
// Both contexts share the same engine resources
91
context1.eval("python", "import sys; version1 = sys.version");
92
context2.eval("python", "import sys; version2 = sys.version");
93
94
// Contexts are isolated but share engine optimizations
95
context1.getBindings("python").putMember("shared_value", 42);
96
// context2 cannot see shared_value unless explicitly shared
97
}
98
} // Engine automatically closed
99
```
100
101
### Engine Builder Configuration
102
103
Configure engines with advanced options for performance, security, and debugging.
104
105
```java { .api }
106
/**
107
* Builder class for creating configured Engine instances
108
*/
109
public static final class Engine.Builder {
110
/**
111
* Allows experimental options to be used (required for some advanced features)
112
* @param enabled true to allow experimental options
113
* @return this builder
114
*/
115
public Builder allowExperimentalOptions(boolean enabled);
116
117
/**
118
* Sets an engine option
119
* @param key option key
120
* @param value option value
121
* @return this builder
122
*/
123
public Builder option(String key, String value);
124
125
/**
126
* Sets multiple engine options
127
* @param options map of option key-value pairs
128
* @return this builder
129
*/
130
public Builder options(Map<String, String> options);
131
132
/**
133
* Sets the output stream for engine messages
134
* @param out OutputStream for engine output
135
* @return this builder
136
*/
137
public Builder out(OutputStream out);
138
139
/**
140
* Sets the error stream for engine error messages
141
* @param err OutputStream for engine errors
142
* @return this builder
143
*/
144
public Builder err(OutputStream err);
145
146
/**
147
* Sets the working directory for the engine
148
* @param workingDirectory path to working directory
149
* @return this builder
150
*/
151
public Builder currentWorkingDirectory(Path workingDirectory);
152
153
/**
154
* Builds the configured Engine
155
* @return new Engine instance
156
*/
157
public Engine build();
158
}
159
```
160
161
**Usage Examples:**
162
163
```java
164
// Advanced engine configuration
165
Engine configuredEngine = Engine.newBuilder()
166
.allowExperimentalOptions(true)
167
.option("engine.WarnInterpreterOnly", "false")
168
.option("compiler.CompilationThreshold", "1000")
169
.out(System.out)
170
.err(System.err)
171
.currentWorkingDirectory(Paths.get("/app/workspace"))
172
.build();
173
174
// Performance-oriented configuration
175
Map<String, String> performanceOptions = Map.of(
176
"engine.BackgroundCompilation", "true",
177
"engine.Compilation", "true",
178
"engine.CompileImmediately", "false",
179
"compiler.CompilationThreshold", "500"
180
);
181
182
Engine performanceEngine = Engine.newBuilder()
183
.allowExperimentalOptions(true)
184
.options(performanceOptions)
185
.build();
186
187
// Debug-oriented configuration
188
Engine debugEngine = Engine.newBuilder()
189
.allowExperimentalOptions(true)
190
.option("engine.TraceCompilation", "true")
191
.option("engine.PrintGraph", "Network")
192
.option("compiler.TraceTruffleCompilation", "true")
193
.build();
194
195
// Custom output streams for logging
196
ByteArrayOutputStream engineOut = new ByteArrayOutputStream();
197
ByteArrayOutputStream engineErr = new ByteArrayOutputStream();
198
199
Engine loggingEngine = Engine.newBuilder()
200
.out(engineOut)
201
.err(engineErr)
202
.build();
203
204
// Use engine and check output
205
try (Context ctx = Context.newBuilder("python").engine(loggingEngine).build()) {
206
ctx.eval("python", "print('Hello from Python')");
207
String output = engineOut.toString();
208
System.out.println("Captured output: " + output);
209
}
210
```
211
212
### Language Discovery and Metadata
213
214
Access detailed information about installed language implementations.
215
216
```java { .api }
217
/**
218
* Represents an installed language implementation
219
*/
220
public final class Language {
221
/**
222
* Gets the unique language identifier
223
* @return language ID (e.g., "python", "js", "ruby")
224
*/
225
public String getId();
226
227
/**
228
* Gets the human-readable language name
229
* @return display name (e.g., "Python", "JavaScript", "Ruby")
230
*/
231
public String getName();
232
233
/**
234
* Gets the implementation name
235
* @return implementation name (e.g., "GraalPy", "GraalJS")
236
*/
237
public String getImplementationName();
238
239
/**
240
* Gets the language version
241
* @return version string (e.g., "3.11.0", "ES2022")
242
*/
243
public String getVersion();
244
245
/**
246
* Checks if the language supports interactive evaluation
247
* @return true if interactive mode is supported
248
*/
249
public boolean isInteractive();
250
251
/**
252
* Gets the language-specific options
253
* @return OptionDescriptors for this language
254
*/
255
public OptionDescriptors getOptions();
256
257
/**
258
* Gets the default MIME type for this language
259
* @return default MIME type (e.g., "text/x-python")
260
*/
261
public String getDefaultMimeType();
262
263
/**
264
* Gets all supported MIME types
265
* @return Set of supported MIME types
266
*/
267
public Set<String> getMimeTypes();
268
269
/**
270
* Gets the language website URL
271
* @return website URL, or null if not available
272
*/
273
public String getWebsite();
274
}
275
```
276
277
**Usage Examples:**
278
279
```java
280
Engine engine = Engine.create();
281
Map<String, Language> languages = engine.getLanguages();
282
283
// Detailed Python language inspection
284
Language python = languages.get("python");
285
if (python != null) {
286
System.out.println("Language ID: " + python.getId()); // python
287
System.out.println("Name: " + python.getName()); // Python
288
System.out.println("Implementation: " + python.getImplementationName()); // GraalPy
289
System.out.println("Version: " + python.getVersion()); // 3.11.0
290
System.out.println("Interactive: " + python.isInteractive()); // true
291
System.out.println("Default MIME: " + python.getDefaultMimeType()); // text/x-python
292
System.out.println("All MIME types: " + python.getMimeTypes());
293
System.out.println("Website: " + python.getWebsite());
294
295
// Check language options
296
OptionDescriptors options = python.getOptions();
297
System.out.println("Available options:");
298
for (OptionDescriptor option : options) {
299
System.out.println("- " + option.getName() + ": " + option.getHelp());
300
}
301
}
302
303
// Language capability detection
304
public class LanguageCapabilities {
305
public static void analyzeLanguage(Language lang) {
306
System.out.println("\nAnalyzing " + lang.getName() + ":");
307
308
// Basic info
309
System.out.println(" ID: " + lang.getId());
310
System.out.println(" Version: " + lang.getVersion());
311
System.out.println(" Implementation: " + lang.getImplementationName());
312
313
// Capabilities
314
System.out.println(" Interactive mode: " + (lang.isInteractive() ? "Yes" : "No"));
315
System.out.println(" MIME types: " + lang.getMimeTypes().size());
316
317
// Options count
318
OptionDescriptors options = lang.getOptions();
319
System.out.println(" Configuration options: " + options.iterator().spliterator().getExactSizeIfKnown());
320
}
321
}
322
323
// Analyze all available languages
324
for (Language lang : languages.values()) {
325
LanguageCapabilities.analyzeLanguage(lang);
326
}
327
328
// Find languages by capability
329
List<Language> interactiveLanguages = languages.values().stream()
330
.filter(Language::isInteractive)
331
.toList();
332
333
System.out.println("\nInteractive languages:");
334
interactiveLanguages.forEach(lang ->
335
System.out.println("- " + lang.getName() + " (" + lang.getId() + ")"));
336
337
// MIME type mapping
338
Map<String, Language> mimeToLanguage = new HashMap<>();
339
for (Language lang : languages.values()) {
340
for (String mimeType : lang.getMimeTypes()) {
341
mimeToLanguage.put(mimeType, lang);
342
}
343
}
344
345
// Use MIME type to determine language
346
String pythonScript = "print('Hello')";
347
String mimeType = "text/x-python";
348
Language detectedLang = mimeToLanguage.get(mimeType);
349
if (detectedLang != null) {
350
System.out.println("MIME type " + mimeType + " maps to " + detectedLang.getName());
351
}
352
```
353
354
### Context-Engine Integration
355
356
Use shared engines across multiple contexts for improved performance and resource efficiency.
357
358
```java { .api }
359
/**
360
* Context.Builder methods for engine integration
361
*/
362
public static final class Context.Builder {
363
/**
364
* Uses the specified engine for this context
365
* @param engine the Engine to use
366
* @return this builder
367
*/
368
public Builder engine(Engine engine);
369
}
370
```
371
372
**Usage Examples:**
373
374
```java
375
// Shared engine for multiple contexts
376
Engine sharedEngine = Engine.newBuilder()
377
.allowExperimentalOptions(true)
378
.option("engine.BackgroundCompilation", "true")
379
.build();
380
381
// Create multiple contexts using the same engine
382
List<Context> contexts = new ArrayList<>();
383
try {
384
for (int i = 0; i < 5; i++) {
385
Context ctx = Context.newBuilder("python")
386
.engine(sharedEngine)
387
.build();
388
contexts.add(ctx);
389
}
390
391
// All contexts share engine optimizations and compiled code
392
for (int i = 0; i < contexts.size(); i++) {
393
Context ctx = contexts.get(i);
394
ctx.eval("python", String.format("""
395
def factorial(n):
396
return 1 if n <= 1 else n * factorial(n-1)
397
398
result_%d = factorial(10)
399
print(f"Context %d: {result_%d}")
400
""", i, i, i));
401
}
402
403
} finally {
404
// Close all contexts
405
for (Context ctx : contexts) {
406
ctx.close();
407
}
408
sharedEngine.close();
409
}
410
411
// Engine pooling for web applications
412
public class EnginePool {
413
private final Engine sharedEngine;
414
private final Semaphore contextLimiter;
415
416
public EnginePool(int maxConcurrentContexts) {
417
this.sharedEngine = Engine.newBuilder()
418
.allowExperimentalOptions(true)
419
.option("engine.BackgroundCompilation", "true")
420
.option("engine.CompilationStatistics", "true")
421
.build();
422
this.contextLimiter = new Semaphore(maxConcurrentContexts);
423
}
424
425
public <T> T executeScript(String script, Function<Context, T> operation) {
426
try {
427
contextLimiter.acquire();
428
try (Context context = Context.newBuilder("python").engine(sharedEngine).build()) {
429
return operation.apply(context);
430
}
431
} catch (InterruptedException e) {
432
Thread.currentThread().interrupt();
433
throw new RuntimeException(e);
434
} finally {
435
contextLimiter.release();
436
}
437
}
438
439
public void close() {
440
sharedEngine.close();
441
}
442
}
443
444
// Usage of engine pool
445
EnginePool enginePool = new EnginePool(10);
446
447
// Execute scripts using pooled engine
448
String result1 = enginePool.executeScript("2 + 2", ctx -> {
449
Value result = ctx.eval("python", "2 + 2");
450
return result.asString();
451
});
452
453
String result2 = enginePool.executeScript("'hello'.upper()", ctx -> {
454
Value result = ctx.eval("python", "'hello'.upper()");
455
return result.asString();
456
});
457
458
enginePool.close();
459
```
460
461
### Instrument Management
462
463
Access and configure debugging and profiling instruments.
464
465
```java { .api }
466
/**
467
* Represents an installed instrument for debugging/profiling
468
*/
469
public final class Instrument {
470
/**
471
* Gets the unique instrument identifier
472
* @return instrument ID
473
*/
474
public String getId();
475
476
/**
477
* Gets the human-readable instrument name
478
* @return display name
479
*/
480
public String getName();
481
482
/**
483
* Gets the instrument version
484
* @return version string
485
*/
486
public String getVersion();
487
488
/**
489
* Gets the instrument-specific options
490
* @return OptionDescriptors for this instrument
491
*/
492
public OptionDescriptors getOptions();
493
494
/**
495
* Looks up instrument services by type
496
* @param <T> service type
497
* @param type the service class
498
* @return service instance, or null if not available
499
*/
500
public <T> T lookup(Class<T> type);
501
}
502
```
503
504
**Usage Examples:**
505
506
```java
507
Engine engine = Engine.create();
508
Map<String, Instrument> instruments = engine.getInstruments();
509
510
// List available instruments
511
System.out.println("Available instruments:");
512
for (Map.Entry<String, Instrument> entry : instruments.entrySet()) {
513
Instrument instrument = entry.getValue();
514
System.out.println("- " + entry.getKey() + ": " + instrument.getName() + " v" + instrument.getVersion());
515
}
516
517
// Check for specific instruments
518
if (instruments.containsKey("profiler")) {
519
Instrument profiler = instruments.get("profiler");
520
System.out.println("Profiler available: " + profiler.getName());
521
522
// Get profiler options
523
OptionDescriptors profilerOptions = profiler.getOptions();
524
System.out.println("Profiler options:");
525
for (OptionDescriptor option : profilerOptions) {
526
System.out.println(" " + option.getName() + ": " + option.getHelp());
527
}
528
}
529
530
// Enable instruments with engine options
531
Engine instrumentedEngine = Engine.newBuilder()
532
.allowExperimentalOptions(true)
533
.option("profiler", "true")
534
.option("profiler.Output", "json")
535
.option("debugger", "true")
536
.build();
537
538
// Use instrumented engine
539
try (Context ctx = Context.newBuilder("python").engine(instrumentedEngine).build()) {
540
// Code execution will be profiled/debugged
541
ctx.eval("python", """
542
def complex_function():
543
total = 0
544
for i in range(1000):
545
total += i * i
546
return total
547
548
result = complex_function()
549
print(f"Result: {result}")
550
""");
551
}
552
553
instrumentedEngine.close();
554
```
555
556
### Performance Monitoring
557
558
Monitor engine performance and resource usage.
559
560
```java { .api }
561
/**
562
* Get performance statistics and metrics from the engine
563
*/
564
public class EngineMetrics {
565
public static void printEngineStats(Engine engine) {
566
System.out.println("Engine Information:");
567
System.out.println(" Version: " + engine.getVersion());
568
System.out.println(" Closed: " + engine.isClosed());
569
570
Map<String, Language> languages = engine.getLanguages();
571
System.out.println(" Languages: " + languages.size());
572
573
Map<String, Instrument> instruments = engine.getInstruments();
574
System.out.println(" Instruments: " + instruments.size());
575
}
576
}
577
```
578
579
**Usage Examples:**
580
581
```java
582
// Performance monitoring setup
583
Engine monitoredEngine = Engine.newBuilder()
584
.allowExperimentalOptions(true)
585
.option("engine.CompilationStatistics", "true")
586
.option("engine.TraceCompilation", "true")
587
.build();
588
589
// Monitor performance during execution
590
EngineMetrics.printEngineStats(monitoredEngine);
591
592
// Execute workload
593
try (Context ctx = Context.newBuilder("python").engine(monitoredEngine).build()) {
594
long startTime = System.currentTimeMillis();
595
596
// Execute Python code multiple times to trigger compilation
597
for (int i = 0; i < 100; i++) {
598
ctx.eval("python", """
599
def fibonacci(n):
600
return n if n <= 1 else fibonacci(n-1) + fibonacci(n-2)
601
fibonacci(20)
602
""");
603
}
604
605
long endTime = System.currentTimeMillis();
606
System.out.println("Execution time: " + (endTime - startTime) + "ms");
607
}
608
609
EngineMetrics.printEngineStats(monitoredEngine);
610
monitoredEngine.close();
611
612
// Resource usage monitoring
613
Runtime runtime = Runtime.getRuntime();
614
long memoryBefore = runtime.totalMemory() - runtime.freeMemory();
615
616
Engine resourceEngine = Engine.create();
617
try (Context ctx = Context.newBuilder("python").engine(resourceEngine).build()) {
618
// Heavy workload
619
ctx.eval("python", """
620
# Create large data structures
621
data = []
622
for i in range(100000):
623
data.append({'id': i, 'value': i * 2, 'description': f'Item {i}'})
624
625
# Process data
626
result = sum(item['value'] for item in data if item['id'] % 2 == 0)
627
print(f"Result: {result}")
628
""");
629
}
630
631
long memoryAfter = runtime.totalMemory() - runtime.freeMemory();
632
System.out.println("Memory usage: " + (memoryAfter - memoryBefore) / 1024 / 1024 + " MB");
633
634
resourceEngine.close();
635
```
636
637
## Types
638
639
```java { .api }
640
/**
641
* Descriptor for engine and language options
642
*/
643
public interface OptionDescriptor {
644
/**
645
* Gets the option name
646
* @return option name
647
*/
648
String getName();
649
650
/**
651
* Gets the option help text
652
* @return help description
653
*/
654
String getHelp();
655
656
/**
657
* Gets the option category
658
* @return category name
659
*/
660
OptionCategory getCategory();
661
662
/**
663
* Gets the option stability level
664
* @return stability level
665
*/
666
OptionStability getStability();
667
668
/**
669
* Checks if this is a deprecated option
670
* @return true if deprecated
671
*/
672
boolean isDeprecated();
673
674
/**
675
* Gets the option key for use in configuration
676
* @return OptionKey instance
677
*/
678
OptionKey<?> getKey();
679
}
680
681
/**
682
* Collection of option descriptors
683
*/
684
public interface OptionDescriptors extends Iterable<OptionDescriptor> {
685
/**
686
* Gets an option descriptor by name
687
* @param name the option name
688
* @return OptionDescriptor, or null if not found
689
*/
690
OptionDescriptor get(String name);
691
}
692
693
/**
694
* Option stability levels
695
*/
696
public enum OptionStability {
697
STABLE, // Stable public API
698
EXPERIMENTAL // Experimental feature
699
}
700
701
/**
702
* Option categories for organization
703
*/
704
public enum OptionCategory {
705
USER, // User-facing options
706
EXPERT, // Expert/advanced options
707
DEBUG // Debug/internal options
708
}
709
```