or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mdengine-factory.mdindex.mdscript-engine.md

configuration.mddocs/

0

# Configuration & Context Management

1

2

Advanced configuration capabilities for GraalJS ScriptEngine including security settings, performance options, and polyglot context management. Provides multiple configuration approaches from simple binding-based options to full polyglot context builders.

3

4

## Capabilities

5

6

### Direct Engine Creation

7

8

Static factory methods for creating GraalJSScriptEngine instances with various levels of customization.

9

10

```java { .api }

11

/**

12

* Creates a new GraalJSScriptEngine with default configuration

13

* Default includes syntax extensions, load/print/arguments support enabled

14

* @return New GraalJSScriptEngine with standard settings

15

*/

16

static GraalJSScriptEngine create();

17

18

/**

19

* Creates a new GraalJSScriptEngine with custom polyglot engine and context configuration

20

* @param engine Polyglot engine to use (null for default)

21

* @param newContextConfig Base configuration for new contexts (null for default)

22

* @return New GraalJSScriptEngine with custom configuration

23

*/

24

static GraalJSScriptEngine create(Engine engine, Context.Builder newContextConfig);

25

```

26

27

**Usage Examples:**

28

29

```java

30

// Simple default creation

31

GraalJSScriptEngine defaultEngine = GraalJSScriptEngine.create();

32

defaultEngine.eval("console.log('Hello, World!');");

33

34

// Custom engine with specific options

35

Engine customEngine = Engine.newBuilder()

36

.allowExperimentalOptions(true)

37

.option("engine.MaxCompilationDelay", "5000")

38

.build();

39

40

Context.Builder contextConfig = Context.newBuilder("js")

41

.allowHostAccess(HostAccess.ALL)

42

.allowIO(IOAccess.ALL)

43

.option("js.ecmascript-version", "2022");

44

45

GraalJSScriptEngine customEngine = GraalJSScriptEngine.create(customEngine, contextConfig);

46

47

// Custom configuration without custom engine

48

GraalJSScriptEngine configuredEngine = GraalJSScriptEngine.create(null, contextConfig);

49

```

50

51

### Polyglot Context Access

52

53

Direct access to underlying GraalVM polyglot contexts for advanced operations and fine-grained control.

54

55

```java { .api }

56

/**

57

* Returns the polyglot context associated with the default ScriptContext

58

* @return GraalVM polyglot Context instance

59

*/

60

Context getPolyglotContext();

61

62

/**

63

* Returns the polyglot context associated with a specific ScriptContext

64

* If context not initialized, creates it using default context builder

65

* @param scriptContext The ScriptContext to get polyglot context for

66

* @return GraalVM polyglot Context instance for the ScriptContext

67

*/

68

Context getPolyglotContext(ScriptContext scriptContext);

69

70

/**

71

* Returns the polyglot engine associated with this script engine

72

* @return GraalVM polyglot Engine instance

73

*/

74

Engine getPolyglotEngine();

75

```

76

77

**Usage Examples:**

78

79

```java

80

GraalJSScriptEngine engine = GraalJSScriptEngine.create();

81

82

// Access default polyglot context

83

Context defaultContext = engine.getPolyglotContext();

84

Value jsBindings = defaultContext.getBindings("js");

85

jsBindings.putMember("javaObject", new Object());

86

87

// Work with multiple script contexts

88

SimpleScriptContext context1 = new SimpleScriptContext();

89

SimpleScriptContext context2 = new SimpleScriptContext();

90

91

Context polyContext1 = engine.getPolyglotContext(context1);

92

Context polyContext2 = engine.getPolyglotContext(context2);

93

94

// Each ScriptContext has its own polyglot context

95

assert polyContext1 != polyContext2;

96

assert polyContext1.getEngine() == polyContext2.getEngine();

97

98

// Direct polyglot operations

99

polyContext1.eval("js", "var ctx1Variable = 'context1'");

100

polyContext2.eval("js", "var ctx2Variable = 'context2'");

101

102

// Access polyglot engine

103

Engine polyEngine = engine.getPolyglotEngine();

104

System.out.println("Engine version: " + polyEngine.getVersion());

105

```

106

107

### Magic Binding Configuration

108

109

Configure GraalJS context options through special binding keys that are processed during context initialization.

110

111

```java { .api }

112

// Magic binding option prefix constant

113

static final String MAGIC_OPTION_PREFIX = "polyglot.js.";

114

115

// Magic binding option keys (set via Bindings.put() before context initialization)

116

"polyglot.js.allowHostAccess" // Boolean - Enable/disable host object access

117

"polyglot.js.allowNativeAccess" // Boolean - Enable/disable native library access

118

"polyglot.js.allowCreateThread" // Boolean - Enable/disable thread creation

119

"polyglot.js.allowIO" // Boolean - Enable/disable I/O operations

120

"polyglot.js.allowHostClassLookup" // Boolean or Predicate<String> - Control class lookup

121

"polyglot.js.allowHostClassLoading" // Boolean - Enable/disable class loading

122

"polyglot.js.allowAllAccess" // Boolean - Enable/disable all access permissions

123

"polyglot.js.nashorn-compat" // Boolean - Enable/disable Nashorn compatibility mode

124

"polyglot.js.ecmascript-version" // String - Set ECMAScript version

125

"polyglot.js.intl-402" // Boolean - Enable/disable Intl API support

126

```

127

128

**Usage Examples:**

129

130

```java

131

ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");

132

Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);

133

134

// Configure security options BEFORE first evaluation

135

bindings.put("polyglot.js.allowHostAccess", true);

136

bindings.put("polyglot.js.allowHostClassLookup", (Predicate<String>) s -> s.startsWith("java."));

137

bindings.put("polyglot.js.allowIO", false); // Disable I/O for security

138

139

// Configure language options

140

bindings.put("polyglot.js.ecmascript-version", "2022");

141

bindings.put("polyglot.js.nashorn-compat", false);

142

143

// Set Java objects accessible to JavaScript

144

bindings.put("javaList", Arrays.asList(1, 2, 3));

145

bindings.put("javaMap", Map.of("key", "value"));

146

147

// Now evaluate - context will be initialized with configured options

148

engine.eval("console.log(javaList.length);"); // Works due to allowHostAccess

149

engine.eval("console.log(Java.type('java.lang.String'));"); // Works due to allowHostClassLookup

150

151

// Attempting to set magic options after context initialization fails

152

try {

153

engine.eval("var dummy = true;"); // Forces context initialization

154

bindings.put("polyglot.js.allowIO", true); // This will throw IllegalStateException

155

} catch (IllegalStateException e) {

156

System.out.println("Cannot set options after context initialization");

157

}

158

```

159

160

### System Property Configuration

161

162

Configure GraalJS options globally through JVM system properties.

163

164

**System Property Format:**

165

```bash

166

# Engine options (affect all ScriptEngine instances)

167

-Dpolyglot.js.ecmascript-version=2022

168

-Dpolyglot.js.intl-402=true

169

170

# Global compatibility mode

171

-Dpolyglot.js.nashorn-compat=true

172

173

# Insecure access mode (development only)

174

-Dgraaljs.insecure-scriptengine-access=true

175

```

176

177

**Usage Examples:**

178

179

```java

180

// Set system properties programmatically (before creating engines)

181

System.setProperty("polyglot.js.ecmascript-version", "2022");

182

System.setProperty("polyglot.js.intl-402", "true");

183

184

// Create engines - they inherit system property settings

185

ScriptEngine engine1 = new ScriptEngineManager().getEngineByName("js");

186

ScriptEngine engine2 = new ScriptEngineManager().getEngineByName("js");

187

188

// Both engines use ES2022 with Intl support

189

engine1.eval("console.log(Object.hasOwn({}, 'prop'));"); // ES2022 feature

190

engine2.eval("console.log(new Intl.DateTimeFormat('en-US'));"); // Intl API

191

192

// Command line usage:

193

// java -Dpolyglot.js.ecmascript-version=2022 -Dpolyglot.js.nashorn-compat=true MyApp

194

```

195

196

### Custom Context Builder Configuration

197

198

Full control over polyglot context configuration through direct Context.Builder usage.

199

200

```java { .api }

201

/**

202

* Example Context.Builder configuration options

203

*/

204

Context.Builder contextBuilder = Context.newBuilder("js")

205

// Security settings

206

.allowHostAccess(HostAccess.ALL) // Or HostAccess.NONE, custom HostAccess

207

.allowHostClassLookup(s -> true) // Or specific predicate

208

.allowHostClassLoading(true)

209

.allowNativeAccess(true)

210

.allowCreateThread(true)

211

.allowIO(IOAccess.ALL) // Or IOAccess.NONE

212

.allowAllAccess(true) // Enables all permissions

213

214

// Language options

215

.option("js.ecmascript-version", "2022")

216

.option("js.intl-402", "true")

217

.option("js.nashorn-compat", "true")

218

.option("js.syntax-extensions", "true")

219

220

// I/O configuration

221

.in(System.in)

222

.out(System.out)

223

.err(System.err)

224

225

// Engine configuration

226

.allowExperimentalOptions(true);

227

```

228

229

**Usage Examples:**

230

231

```java

232

// Secure configuration for untrusted code

233

Context.Builder secureConfig = Context.newBuilder("js")

234

.allowHostAccess(HostAccess.NONE)

235

.allowHostClassLookup(s -> false)

236

.allowHostClassLoading(false)

237

.allowNativeAccess(false)

238

.allowCreateThread(false)

239

.allowIO(IOAccess.NONE)

240

.option("js.ecmascript-version", "2022");

241

242

GraalJSScriptEngine secureEngine = GraalJSScriptEngine.create(null, secureConfig);

243

244

// Permissive configuration for trusted code

245

Context.Builder permissiveConfig = Context.newBuilder("js")

246

.allowAllAccess(true)

247

.allowHostClassLookup(s -> true)

248

.option("js.nashorn-compat", "true")

249

.option("js.ecmascript-version", "2022");

250

251

GraalJSScriptEngine permissiveEngine = GraalJSScriptEngine.create(null, permissiveConfig);

252

253

// Development configuration with custom I/O

254

StringWriter output = new StringWriter();

255

StringWriter errors = new StringWriter();

256

257

Context.Builder devConfig = Context.newBuilder("js")

258

.allowAllAccess(true)

259

.out(new WriterOutputStream(output, StandardCharsets.UTF_8))

260

.err(new WriterOutputStream(errors, StandardCharsets.UTF_8))

261

.option("js.syntax-extensions", "true");

262

263

GraalJSScriptEngine devEngine = GraalJSScriptEngine.create(null, devConfig);

264

devEngine.eval("console.log('Hello'); console.error('Warning');");

265

System.out.println("Output: " + output.toString());

266

System.out.println("Errors: " + errors.toString());

267

```

268

269

### Nashorn Compatibility Mode

270

271

Special compatibility mode for applications migrating from Oracle Nashorn ScriptEngine.

272

273

```java { .api }

274

// Enable via system property

275

System.setProperty("polyglot.js.nashorn-compat", "true");

276

277

// Enable via magic binding

278

bindings.put("polyglot.js.nashorn-compat", true);

279

280

// Enable via context builder

281

Context.Builder nashornConfig = Context.newBuilder("js")

282

.option("js.nashorn-compat", "true");

283

```

284

285

**Nashorn Compatibility Features:**

286

- Automatic host access permissions

287

- Nashorn-style type conversions

288

- Extended compatibility for legacy code

289

- System.exit() support

290

291

**Usage Examples:**

292

293

```java

294

// Global Nashorn compatibility

295

System.setProperty("polyglot.js.nashorn-compat", "true");

296

ScriptEngine nashornCompatEngine = new ScriptEngineManager().getEngineByName("js");

297

298

// Nashorn-style operations work automatically

299

nashornCompatEngine.put("javaObject", new Object());

300

nashornCompatEngine.eval("print(javaObject.getClass().getName());");

301

302

// Per-engine Nashorn compatibility

303

ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");

304

Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);

305

bindings.put("polyglot.js.nashorn-compat", true);

306

bindings.put("polyglot.js.allowAllAccess", true);

307

308

engine.eval("var ArrayList = Java.type('java.util.ArrayList');");

309

engine.eval("var list = new ArrayList(); list.add('item');");

310

```

311

312

### Resource Management

313

314

Proper lifecycle management of engines, contexts, and associated resources.

315

316

```java { .api }

317

/**

318

* Closes the current context and makes it unusable

319

* Operations performed after closing will throw IllegalStateException

320

*/

321

void close();

322

323

/**

324

* Check if context is closed

325

*/

326

boolean isClosed(); // Available on polyglot Context

327

```

328

329

**Usage Examples:**

330

331

```java

332

// Automatic resource management

333

try (GraalJSScriptEngine engine = GraalJSScriptEngine.create()) {

334

engine.eval("console.log('Working...');");

335

// Engine automatically closed when leaving try block

336

}

337

338

// Manual resource management

339

GraalJSScriptEngine engine = GraalJSScriptEngine.create();

340

try {

341

engine.eval("var result = computeExpensiveOperation();");

342

Object result = engine.get("result");

343

return result;

344

} finally {

345

engine.close(); // Ensure cleanup

346

}

347

348

// Managing polyglot contexts directly

349

Context polyglotContext = engine.getPolyglotContext();

350

try {

351

polyglotContext.eval("js", "performWork()");

352

} finally {

353

if (!polyglotContext.isClosed()) {

354

polyglotContext.close();

355

}

356

}

357

358

// Resource sharing with custom engine

359

Engine sharedEngine = Engine.newBuilder().build();

360

try {

361

GraalJSScriptEngine engine1 = GraalJSScriptEngine.create(sharedEngine, null);

362

GraalJSScriptEngine engine2 = GraalJSScriptEngine.create(sharedEngine, null);

363

364

// Use both engines - they share the polyglot engine

365

engine1.eval("var shared = 'data';");

366

engine2.eval("var other = 'data';");

367

368

// Close individual engines

369

engine1.close();

370

engine2.close();

371

} finally {

372

// Close shared engine when all ScriptEngines are done

373

sharedEngine.close();

374

}

375

```

376

377

## Configuration Best Practices

378

379

### Security Configuration

380

- Always use minimal required permissions

381

- Disable host access for untrusted code

382

- Use allowHostClassLookup predicates to restrict class access

383

- Disable I/O and native access unless required

384

385

### Performance Configuration

386

- Reuse ScriptEngine instances when possible

387

- Use CompiledScript for repeated execution

388

- Share polyglot Engine across multiple ScriptEngines

389

- Enable experimental options for performance tuning

390

391

### Migration from Nashorn

392

- Enable nashorn-compat mode initially

393

- Gradually migrate to modern GraalJS features

394

- Test thoroughly as compatibility is not 100%

395

- Consider direct polyglot API for new development