or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdjava-integration.mdjavascript-objects.mdscript-execution.mdsecurity-debugging.md

java-integration.mddocs/

0

# Java Integration

1

2

Comprehensive Java-JavaScript interoperability system providing seamless bidirectional communication, automatic type conversion, Java class access, and adapter objects for implementing Java interfaces with JavaScript.

3

4

## Capabilities

5

6

### Type Conversion

7

8

Automatic conversion between Java and JavaScript values with comprehensive type mapping and coercion rules.

9

10

```java { .api }

11

/**

12

* Converts Java object to JavaScript representation

13

* @param value Java object to convert

14

* @param scope JavaScript scope for object creation

15

* @return JavaScript representation of Java object

16

*/

17

public static Object javaToJS(Object value, Scriptable scope);

18

19

/**

20

* Converts Java object to JavaScript representation with explicit Context

21

* @param value Java object to convert

22

* @param scope JavaScript scope for object creation

23

* @param cx Context for the conversion

24

* @return JavaScript representation of Java object

25

*/

26

public static Object javaToJS(Object value, Scriptable scope, Context cx);

27

28

/**

29

* Converts JavaScript value to Java object of specified type

30

* @param value JavaScript value to convert

31

* @param desiredType Target Java class/interface

32

* @return Java object of desired type

33

*/

34

public static Object jsToJava(Object value, Class<?> desiredType);

35

36

/**

37

* Converts JavaScript value to boolean

38

* @param value JavaScript value

39

* @return boolean representation

40

*/

41

public static boolean toBoolean(Object value);

42

43

/**

44

* Converts JavaScript value to number

45

* @param value JavaScript value

46

* @return double representation

47

*/

48

public static double toNumber(Object value);

49

50

/**

51

* Converts JavaScript value to string

52

* @param value JavaScript value

53

* @return String representation

54

*/

55

public static String toString(Object value);

56

57

/**

58

* Converts JavaScript value to Scriptable object

59

* @param value JavaScript value

60

* @param scope Scope for object creation

61

* @return Scriptable representation

62

*/

63

public static Scriptable toObject(Object value, Scriptable scope);

64

```

65

66

**Usage Examples:**

67

68

```java

69

// Java to JavaScript conversion

70

List<String> javaList = Arrays.asList("a", "b", "c");

71

Object jsArray = Context.javaToJS(javaList, scope);

72

73

// JavaScript to Java conversion

74

String jsString = "42";

75

Object jsNumber = cx.evaluateString(scope, jsString, "test", 1, null);

76

Integer javaInt = (Integer) Context.jsToJava(jsNumber, Integer.class);

77

78

// Type coercion examples

79

Object jsValue = cx.evaluateString(scope, "true", "test", 1, null);

80

boolean javaBool = Context.toBoolean(jsValue); // true

81

double javaNum = Context.toNumber(jsValue); // 1.0

82

String javaStr = Context.toString(jsValue); // "true"

83

84

// Converting JavaScript objects

85

Object jsObj = cx.evaluateString(scope, "({name: 'test', value: 42})", "test", 1, null);

86

Map<String, Object> javaMap = (Map<String, Object>) Context.jsToJava(jsObj, Map.class);

87

```

88

89

### Java Object Wrapping

90

91

Wrapping Java objects for access from JavaScript with automatic method binding and property access.

92

93

```java { .api }

94

/**

95

* JavaScript wrapper for Java objects

96

* Provides property access and method invocation from JavaScript

97

*/

98

public class NativeJavaObject extends ScriptableObject {

99

/**

100

* Creates wrapper for Java object

101

* @param scope JavaScript scope

102

* @param javaObject Java object to wrap

103

* @param staticType Static type for method resolution

104

*/

105

public NativeJavaObject(Scriptable scope, Object javaObject, Class<?> staticType);

106

107

/**

108

* Gets the wrapped Java object

109

* @return Original Java object

110

*/

111

public Object unwrap();

112

113

/**

114

* Gets the static type used for method resolution

115

* @return Java class

116

*/

117

public Class<?> getStaticType();

118

119

/**

120

* Coerces JavaScript value to Java type

121

* @param type Target Java type

122

* @param value JavaScript value to convert

123

* @return Converted Java value

124

*/

125

public static Object coerceTypeImpl(Class<?> type, Object value);

126

}

127

128

/**

129

* JavaScript wrapper for Java classes (not instances)

130

* Allows access to static methods and constructors

131

*/

132

public class NativeJavaClass extends NativeJavaObject {

133

/**

134

* Creates wrapper for Java class

135

* @param scope JavaScript scope

136

* @param cl Java class to wrap

137

*/

138

public NativeJavaClass(Scriptable scope, Class<?> cl);

139

140

/**

141

* Gets the wrapped Java class

142

* @return Java Class object

143

*/

144

public Class<?> getClassObject();

145

}

146

147

/**

148

* JavaScript wrapper for Java methods

149

* Handles method overloading and parameter conversion

150

*/

151

public class NativeJavaMethod extends BaseFunction {

152

/**

153

* Creates wrapper for Java method(s)

154

* @param methods Array of Method objects (for overloading)

155

* @param name Method name for JavaScript

156

*/

157

public NativeJavaMethod(Method[] methods, String name);

158

}

159

160

/**

161

* JavaScript wrapper for Java constructors

162

* Enables 'new' operator usage from JavaScript

163

*/

164

public class NativeJavaConstructor extends BaseFunction {

165

/**

166

* Creates wrapper for Java constructor(s)

167

* @param constructors Array of Constructor objects

168

*/

169

public NativeJavaConstructor(Constructor<?>[] constructors);

170

}

171

```

172

173

**Usage Examples:**

174

175

```java

176

// Wrapping Java objects

177

StringBuilder sb = new StringBuilder("Hello");

178

Object wrappedSB = Context.javaToJS(sb, scope);

179

180

// Accessing from JavaScript

181

String result = (String) cx.evaluateString(scope, """

182

wrappedSB.append(' World');

183

wrappedSB.toString();

184

""", "test", 1, null);

185

System.out.println(result); // "Hello World"

186

187

// Working with Java classes

188

Class<?> stringClass = String.class;

189

Object wrappedClass = Context.javaToJS(stringClass, scope);

190

scope.put("StringClass", scope, wrappedClass);

191

192

// Using static methods from JavaScript

193

Object staticResult = cx.evaluateString(scope, """

194

StringClass.valueOf(123);

195

""", "test", 1, null);

196

```

197

198

### Java Array Integration

199

200

Special handling for Java arrays with JavaScript Array-like syntax and methods.

201

202

```java { .api }

203

/**

204

* JavaScript wrapper for Java arrays

205

* Provides Array-like access and some Array prototype methods

206

*/

207

public class NativeJavaArray extends NativeJavaObject {

208

/**

209

* Creates wrapper for Java array

210

* @param scope JavaScript scope

211

* @param array Java array to wrap

212

*/

213

public NativeJavaArray(Scriptable scope, Object array);

214

215

/**

216

* Gets array length

217

* @return Array length

218

*/

219

public int getLength();

220

221

/**

222

* Gets array element at index

223

* @param index Array index

224

* @return Array element

225

*/

226

public Object get(int index);

227

228

/**

229

* Sets array element at index

230

* @param index Array index

231

* @param value New element value

232

*/

233

public void put(int index, Object value);

234

}

235

```

236

237

**Usage Examples:**

238

239

```java

240

// Working with Java arrays

241

int[] javaArray = {1, 2, 3, 4, 5};

242

Object wrappedArray = Context.javaToJS(javaArray, scope);

243

scope.put("javaArray", scope, wrappedArray);

244

245

// Access from JavaScript with array syntax

246

Object result = cx.evaluateString(scope, """

247

javaArray[2] = 99; // Modify Java array

248

javaArray.length; // Get length

249

""", "test", 1, null);

250

251

// Java array is modified

252

System.out.println(Arrays.toString(javaArray)); // [1, 2, 99, 4, 5]

253

```

254

255

### Java Collection Integration

256

257

Enhanced integration for Java Collection framework classes with JavaScript semantics.

258

259

```java { .api }

260

/**

261

* JavaScript wrapper for Java List implementations

262

* Implements both Scriptable and List interfaces

263

*/

264

public class NativeJavaList extends NativeJavaObject implements List<Object> {

265

/**

266

* Creates wrapper for Java List

267

* @param scope JavaScript scope

268

* @param list Java List to wrap

269

*/

270

public NativeJavaList(Scriptable scope, List<?> list);

271

272

// List interface methods delegated to wrapped list

273

public int size();

274

public boolean isEmpty();

275

public boolean contains(Object o);

276

public Iterator<Object> iterator();

277

public Object[] toArray();

278

public boolean add(Object o);

279

public boolean remove(Object o);

280

public void clear();

281

public Object get(int index);

282

public Object set(int index, Object element);

283

public void add(int index, Object element);

284

public Object remove(int index);

285

}

286

287

/**

288

* JavaScript wrapper for Java Map implementations

289

* Provides Map access with JavaScript object semantics

290

*/

291

public class NativeJavaMap extends NativeJavaObject {

292

/**

293

* Creates wrapper for Java Map

294

* @scope JavaScript scope

295

* @param map Java Map to wrap

296

*/

297

public NativeJavaMap(Scriptable scope, Map<?, ?> map);

298

299

/**

300

* Gets map size

301

* @return Number of key-value pairs

302

*/

303

public int size();

304

305

/**

306

* Checks if key exists

307

* @param key Key to check

308

* @return true if key exists

309

*/

310

public boolean containsKey(Object key);

311

}

312

```

313

314

**Usage Examples:**

315

316

```java

317

// Working with Java Collections

318

List<String> javaList = new ArrayList<>();

319

javaList.addAll(Arrays.asList("a", "b", "c"));

320

Object wrappedList = Context.javaToJS(javaList, scope);

321

scope.put("javaList", scope, wrappedList);

322

323

// Use from JavaScript with array-like syntax

324

cx.evaluateString(scope, """

325

javaList[1] = 'modified'; // Set element

326

javaList.add('d'); // Call List method

327

""", "test", 1, null);

328

329

// Java List is modified

330

System.out.println(javaList); // [a, modified, c, d]

331

332

// Working with Maps

333

Map<String, Object> javaMap = new HashMap<>();

334

javaMap.put("key1", "value1");

335

Object wrappedMap = Context.javaToJS(javaMap, scope);

336

scope.put("javaMap", scope, wrappedMap);

337

338

// Access map from JavaScript

339

Object value = cx.evaluateString(scope, "javaMap.get('key1')", "test", 1, null);

340

```

341

342

### Package and Class Access

343

344

Accessing Java packages and classes from JavaScript with automatic class loading.

345

346

```java { .api }

347

/**

348

* JavaScript representation of Java packages

349

* Allows navigation of package hierarchy from JavaScript

350

*/

351

public class NativeJavaPackage extends ScriptableObject {

352

/**

353

* Creates package wrapper for given package name

354

* @param packageName Java package name (e.g., "java.util")

355

*/

356

public NativeJavaPackage(String packageName);

357

358

/**

359

* Gets package name

360

* @return Package name string

361

*/

362

public String getPackageName();

363

}

364

365

/**

366

* Top-level package objects (java, javax, org, etc.)

367

* Provides root access to Java package hierarchy

368

*/

369

public class NativeJavaTopPackage extends NativeJavaPackage {

370

/**

371

* Creates top-level package (java, javax, etc.)

372

* @param packageName Top-level package name

373

*/

374

public NativeJavaTopPackage(String packageName);

375

}

376

```

377

378

**Usage Examples:**

379

380

```java

381

// Enable Java class access (done automatically with initStandardObjects)

382

ImporterTopLevel importerScope = new ImporterTopLevel(cx);

383

384

// Access Java classes from JavaScript

385

Object result = cx.evaluateString(importerScope, """

386

var ArrayList = java.util.ArrayList;

387

var list = new ArrayList();

388

list.add('item1');

389

list.add('item2');

390

list.size();

391

""", "test", 1, null);

392

System.out.println(result); // 2.0

393

394

// Import classes for easier use

395

cx.evaluateString(importerScope, """

396

importClass(java.util.HashMap);

397

var map = new HashMap();

398

map.put('key', 'value');

399

""", "test", 1, null);

400

```

401

402

### WrapFactory

403

404

Controls how Java objects are wrapped for JavaScript access with customizable wrapping behavior.

405

406

```java { .api }

407

/**

408

* Factory for controlling Java object wrapping

409

* Customize how Java objects appear in JavaScript

410

*/

411

public class WrapFactory {

412

/**

413

* Wraps Java object for JavaScript access

414

* @param cx Current Context

415

* @param scope JavaScript scope

416

* @param obj Java object to wrap

417

* @param staticType Static type for method resolution

418

* @return Wrapped JavaScript object

419

*/

420

public Object wrap(Context cx, Scriptable scope, Object obj, Class<?> staticType);

421

422

/**

423

* Wraps Java object as NativeJavaObject

424

* @param cx Current Context

425

* @param scope JavaScript scope

426

* @param javaObject Java object to wrap

427

* @param staticType Static type

428

* @return NativeJavaObject wrapper

429

*/

430

public Scriptable wrapAsJavaObject(Context cx, Scriptable scope, Object javaObject, Class<?> staticType);

431

432

/**

433

* Wraps Java class as NativeJavaClass

434

* @param cx Current Context

435

* @param scope JavaScript scope

436

* @param javaClass Java class to wrap

437

* @return NativeJavaClass wrapper

438

*/

439

public Scriptable wrapJavaClass(Context cx, Scriptable scope, Class<?> javaClass);

440

441

/**

442

* Wraps new object (return value from constructor or method)

443

* @param cx Current Context

444

* @param scope JavaScript scope

445

* @param obj New Java object

446

* @param staticType Static type

447

* @return Wrapped object

448

*/

449

public Object wrapNewObject(Context cx, Scriptable scope, Object obj);

450

451

/**

452

* Checks if object should be wrapped

453

* @param obj Java object

454

* @param type Static type

455

* @param isStatic true if static context

456

* @return true if object should be wrapped

457

*/

458

public boolean isJavaPrimitiveWrap();

459

}

460

```

461

462

**Usage Examples:**

463

464

```java

465

// Custom WrapFactory to control wrapping behavior

466

WrapFactory customFactory = new WrapFactory() {

467

@Override

468

public Object wrap(Context cx, Scriptable scope, Object obj, Class<?> staticType) {

469

// Custom wrapping logic

470

if (obj instanceof MySpecialClass) {

471

return new MySpecialWrapper(scope, obj, staticType);

472

}

473

return super.wrap(cx, scope, obj, staticType);

474

}

475

};

476

477

// Set custom WrapFactory on Context

478

cx.setWrapFactory(customFactory);

479

480

// Now Java objects will be wrapped using custom logic

481

Object wrapped = Context.javaToJS(new MySpecialClass(), scope);

482

```

483

484

### JavaAdapter

485

486

Creates Java objects that implement interfaces using JavaScript implementations.

487

488

```java { .api }

489

/**

490

* Creates Java objects implementing interfaces with JavaScript

491

* Allows JavaScript functions to implement Java interfaces

492

*/

493

public class JavaAdapter {

494

/**

495

* Creates adapter object implementing Java interfaces

496

* @param jsObj JavaScript object with method implementations

497

* @param adapter Java interface/class to implement

498

* @return Java object implementing interface

499

*/

500

public static Object createAdapterWrapper(Scriptable jsObj, Object adapter);

501

502

/**

503

* Creates adapter class implementing interfaces

504

* @param cx Current Context

505

* @param scope JavaScript scope

506

* @param args Arguments: [interfaces..., constructor, prototype]

507

* @param writeAdapter Whether to write class file

508

* @return Constructor function for adapter class

509

*/

510

public static Scriptable createAdapterClass(Context cx, Scriptable scope, Object[] args, boolean writeAdapter);

511

}

512

```

513

514

**Usage Examples:**

515

516

```java

517

// Implementing Java interface with JavaScript

518

String jsCode = """

519

new java.lang.Runnable({

520

run: function() {

521

print('Running from JavaScript!');

522

}

523

});

524

""";

525

526

Object jsRunnable = cx.evaluateString(scope, jsCode, "adapter", 1, null);

527

Runnable runnable = (Runnable) Context.jsToJava(jsRunnable, Runnable.class);

528

runnable.run(); // Calls JavaScript function

529

530

// More complex interface implementation

531

String listenerCode = """

532

new java.awt.event.ActionListener({

533

actionPerformed: function(event) {

534

print('Action performed: ' + event.getActionCommand());

535

}

536

});

537

""";

538

539

Object jsListener = cx.evaluateString(scope, listenerCode, "listener", 1, null);

540

ActionListener listener = (ActionListener) Context.jsToJava(jsListener, ActionListener.class);

541

```

542

543

### Advanced Integration Features

544

545

#### Method Overloading Resolution

546

547

Rhino automatically resolves Java method overloads based on argument types.

548

549

```java

550

// Java class with overloaded methods

551

public class Calculator {

552

public int add(int a, int b) { return a + b; }

553

public double add(double a, double b) { return a + b; }

554

public String add(String a, String b) { return a + b; }

555

}

556

557

// From JavaScript - automatic overload resolution

558

Calculator calc = new Calculator();

559

Object wrappedCalc = Context.javaToJS(calc, scope);

560

scope.put("calc", scope, wrappedCalc);

561

562

cx.evaluateString(scope, """

563

calc.add(1, 2); // Calls int version -> 3

564

calc.add(1.5, 2.5); // Calls double version -> 4.0

565

calc.add('a', 'b'); // Calls String version -> 'ab'

566

""", "overload", 1, null);

567

```

568

569

#### Bean Property Access

570

571

Automatic property access for Java Bean getter/setter methods.

572

573

```java

574

// Java Bean class

575

public class Person {

576

private String name;

577

private int age;

578

579

public String getName() { return name; }

580

public void setName(String name) { this.name = name; }

581

public int getAge() { return age; }

582

public void setAge(int age) { this.age = age; }

583

}

584

585

// From JavaScript - property-style access

586

Person person = new Person();

587

Object wrappedPerson = Context.javaToJS(person, scope);

588

scope.put("person", scope, wrappedPerson);

589

590

cx.evaluateString(scope, """

591

person.name = 'John'; // Calls setName()

592

person.age = 30; // Calls setAge()

593

594

var name = person.name; // Calls getName()

595

var age = person.age; // Calls getAge()

596

""", "bean", 1, null);

597

```

598

599

### Java Method Binding with FunctionObject

600

601

The FunctionObject class enables direct binding of Java methods and constructors to JavaScript functions with automatic type conversion.

602

603

```java { .api }

604

/**

605

* A JavaScript function object that wraps a Java method or constructor.

606

* Enables binding Java methods to JavaScript functions with automatic

607

* type conversion and proper 'this' handling.

608

*/

609

public class FunctionObject extends BaseFunction {

610

/**

611

* Create a JavaScript function object from a Java method or constructor.

612

* @param name the name of the function

613

* @param methodOrConstructor a java.lang.reflect.Method or Constructor

614

* @param scope enclosing scope of function

615

*/

616

public FunctionObject(String name, Member methodOrConstructor, Scriptable scope);

617

618

/**

619

* Return the arity (number of parameters) of the function.

620

* @return the number of parameters

621

*/

622

public int getArity();

623

624

/**

625

* Get the name of this function.

626

* @return the function name, or empty string if none

627

*/

628

public String getFunctionName();

629

630

/**

631

* Get the underlying Java method or constructor this function represents.

632

* @return the Member (Method or Constructor)

633

*/

634

public Member getMethodOrConstructor();

635

636

/**

637

* Define this function as a JavaScript constructor.

638

* @param scope the scope to define the constructor in

639

* @param prototype the prototype object

640

*/

641

public void addAsConstructor(Scriptable scope, Scriptable prototype);

642

643

// Type conversion utilities

644

public static int getTypeTag(Class<?> type);

645

public static Object convertArg(Context cx, Scriptable scope, Object arg, int typeTag);

646

647

// Type constants for method parameter conversion

648

public static final int JAVA_UNSUPPORTED_TYPE = 0;

649

public static final int JAVA_STRING_TYPE = 1;

650

public static final int JAVA_INT_TYPE = 2;

651

public static final int JAVA_BOOLEAN_TYPE = 3;

652

public static final int JAVA_DOUBLE_TYPE = 4;

653

public static final int JAVA_SCRIPTABLE_TYPE = 5;

654

public static final int JAVA_OBJECT_TYPE = 6;

655

}

656

```

657

658

**Usage Examples:**

659

660

```java

661

// Bind static method to JavaScript function

662

public class MathUtils {

663

public static double square(double x) {

664

return x * x;

665

}

666

667

public static String format(String template, Object... args) {

668

return String.format(template, args);

669

}

670

}

671

672

// Create function binding

673

Method squareMethod = MathUtils.class.getMethod("square", double.class);

674

FunctionObject squareFunction = new FunctionObject("square", squareMethod, scope);

675

scope.put("square", scope, squareFunction);

676

677

// Use from JavaScript

678

Object result = cx.evaluateString(scope, "square(5)", "test", 1, null);

679

System.out.println(result); // 25.0

680

681

// Bind instance method to JavaScript function

682

public class Calculator {

683

private double value = 0;

684

685

public double add(double x) {

686

return value += x;

687

}

688

689

public double getValue() {

690

return value;

691

}

692

}

693

694

Calculator calc = new Calculator();

695

Method addMethod = Calculator.class.getMethod("add", double.class);

696

FunctionObject addFunction = new FunctionObject("add", addMethod, scope);

697

698

// Bind the calculator instance

699

scope.put("calc", scope, Context.javaToJS(calc, scope));

700

scope.put("addToCalc", scope, addFunction);

701

702

// Use from JavaScript - the 'this' binding is handled automatically

703

cx.evaluateString(scope, "addToCalc.call(calc, 10)", "test", 1, null);

704

System.out.println(calc.getValue()); // 10.0

705

706

// Constructor binding

707

public class Point {

708

private double x, y;

709

710

public Point(double x, double y) {

711

this.x = x;

712

this.y = y;

713

}

714

715

public double getX() { return x; }

716

public double getY() { return y; }

717

}

718

719

Constructor<Point> pointConstructor = Point.class.getConstructor(double.class, double.class);

720

FunctionObject pointFunction = new FunctionObject("Point", pointConstructor, scope);

721

722

// Add prototype for the constructor

723

Scriptable pointPrototype = cx.newObject(scope);

724

pointFunction.addAsConstructor(scope, pointPrototype);

725

726

// Use constructor from JavaScript

727

Object pointObj = cx.evaluateString(scope, "new Point(3, 4)", "test", 1, null);

728

// Creates a Point instance accessible from JavaScript

729

```

730

731

#### Exception Handling

732

733

Java exceptions are automatically converted to JavaScript errors.

734

735

```java

736

// Java method that throws exception

737

public class TestClass {

738

public void throwException() throws Exception {

739

throw new IllegalArgumentException("Test exception");

740

}

741

}

742

743

// From JavaScript - exception becomes JavaScript error

744

TestClass test = new TestClass();

745

scope.put("test", scope, Context.javaToJS(test, scope));

746

747

try {

748

cx.evaluateString(scope, """

749

try {

750

test.throwException();

751

} catch (e) {

752

print('Caught: ' + e.message); // "Test exception"

753

print('Java class: ' + e.javaException.getClass().getName());

754

}

755

""", "exception", 1, null);

756

} catch (WrappedException we) {

757

// WrappedException contains the original Java exception

758

Throwable original = we.getWrappedException();

759

}

760

```