Skip to content

Commit c5ed5b7

Browse files
cancerberoSgxjoeferner
authored andcommitted
headings and asyncOptions API
1 parent 38a1e73 commit c5ed5b7

1 file changed

Lines changed: 83 additions & 13 deletions

File tree

README.md

Lines changed: 83 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,8 @@ try {
235235
}
236236
```
237237

238+
<a name="asyncOptions" >
239+
238240
### AsyncOptions: control over the generation of sync, async & promise method variants.
239241

240242
As of release 0.4.5 it became possible to create async methods that return promises by setting the `asyncOptions` property of the java object. With release 0.4.7 this feature is extended to allow changing the suffix assigned for sync and async method variants, and to further configure this module to optionally omit generation of any of these variants.
@@ -272,15 +274,13 @@ java.newInstancePromise("java.util.ArrayList")
272274
* NOTE: Due to specifics of initialization order, the methods `java.newInstancePromise`, `java.callMethodPromise`, and `java.callStaticMethodPromise` are not available until the JVM has been created. You may need to call some other java method such as `java.import()` to finalize java initialization, or even better, the function `java.ensureJvm()`.
273275

274276
##### Special note about the exported module functions `newInstance`, `callMethod`, and `callStaticMethod`.
275-
These methods come in both async and sync variants. If you provide the `promisify` and `promiseSuffix` attributes in asyncOptions then you'll also get the Promises/A+ variant for these three functions. However, if you change the defacto
276-
conventions for the `syncSuffix` (i.e. 'Sync') and/or `asyncSuffix` (i.e. '') it will not affect the naming for these three functions. I.e. no matter what you specify in asyncOptions, the async variants are named `newInstance`, `callMethod`, and `callStaticMethod`, and the sync variants are named `newInstanceSync`, `callMethodSync`, and `callStaticMethodSync`.
277+
These methods come in both async and sync variants. If you provide the `promisify` and `promiseSuffix` attributes in asyncOptions then you'll also get the Promises/A+ variant for these three functions. However, if you change the defacto conventions for the `syncSuffix` (i.e. 'Sync') and/or `asyncSuffix` (i.e. '') it will not affect the naming for these three functions. I.e. no matter what you specify in asyncOptions, the async variants are named `newInstance`, `callMethod`, and `callStaticMethod`, and the sync variants are named `newInstanceSync`, `callMethodSync`, and `callStaticMethodSync`.
277278

278279
## Varargs support
279280

280-
With v0.5.0 node-java now supports methods with variadic arguments (varargs). Prior to v0.5.0,
281-
a javascript call to a Java varargs method had to construct an array of the variadic arguments using `java.newArray()`. With v0.5.0 javascript applications can simply use the variadic style.
281+
With v0.5.0 node-java now supports methods with variadic arguments (varargs). Prior to v0.5.0, a JavaScript call to a Java varargs method had to construct an array of the variadic arguments using `java.newArray()`. With v0.5.0 JavaScript applications can simply use the variadic style.
282282

283-
In most cases it is still acceptable to use `java.newArray()`. But it is now possible to pass a plain javascript array, or use the variadic style. For example, consider these snippets from the unit test file `test/varargs-test.js`:
283+
In most cases it is still acceptable to use `java.newArray()`. But it is now possible to pass a plain JavaScript array, or use the variadic style. For example, consider these snippets from the unit test file `test/varargs-test.js`:
284284

285285
```
286286
test.equal(Test.staticVarargsSync(5, 'a', 'b', 'c'), '5abc');
@@ -289,7 +289,7 @@ In most cases it is still acceptable to use `java.newArray()`. But it is now pos
289289
290290
```
291291

292-
Note that when passing a Javascript array (e.g. `['a', 'b', 'c']`) for a varargs parameter, node-java must infer the Java type of the array. If all of the elements are of the same javascript primitive type (`string` in this example) then node-java will create a Java array of the corresponding type (e.g. `java.lang.String`). The Java types that node-java can infer are: `java.lang.String`, `java.lang.Boolean`, `java.lang.Integer`, `java.lang.Long`, and `java.lang.Double`. If an array has a mix of `Integer`, `Long`, and `Double`, then the inferred type will be `java.lang.Number`. Any other mix will result in an inferred type of `java.lang.Object`.
292+
Note that when passing a JavaScript array (e.g. `['a', 'b', 'c']`) for a varargs parameter, node-java must infer the Java type of the array. If all of the elements are of the same JavaScript primitive type (`string` in this example) then node-java will create a Java array of the corresponding type (e.g. `java.lang.String`). The Java types that node-java can infer are: `java.lang.String`, `java.lang.Boolean`, `java.lang.Integer`, `java.lang.Long`, and `java.lang.Double`. If an array has a mix of `Integer`, `Long`, and `Double`, then the inferred type will be `java.lang.Number`. Any other mix will result in an inferred type of `java.lang.Object`.
293293

294294
Methods accepting varargs of a generic type are also problematic. You will need to fall back to using `java.newArray()`. See [Issue #285](https://github.com/joeferner/node-java/issues/285).
295295

@@ -314,6 +314,7 @@ With v0.5.1 a new API is available to make it easier for a complex application t
314314
## java
315315
* [classpath](#javaClasspath)
316316
* [options](#javaOptions)
317+
* [asyncOptions](#javaAsyncOptions)
317318
* [import](#javaImport)
318319
* [newInstance](#javaNewInstance)
319320
* [instanceOf](#javaInstanceOf)
@@ -346,6 +347,8 @@ With v0.5.1 a new API is available to make it easier for a complex application t
346347

347348
<a name="javaClasspath" >
348349

350+
## classpath
351+
349352
*java.classpath**
350353

351354
Array of paths or jars to pass to the creation of the JVM.
@@ -357,6 +360,8 @@ __Example__
357360
java.classpath.push('commons.io.jar');
358361
java.classpath.push('src');
359362

363+
## options
364+
360365
<a name="javaOptions" >
361366

362367
*java.options**
@@ -370,11 +375,33 @@ __Example__
370375
java.options.push('-Djava.awt.headless=true');
371376
java.options.push('-Xmx1024m');
372377

378+
## asyncOptions
379+
380+
```javascript
381+
java.asyncOptions = {
382+
asyncSuffix: undefined, // Don't generate node-style methods taking callbacks
383+
syncSuffix: "", // Sync methods use the base name(!!)
384+
promiseSuffix: "Promise", // Generate methods returning promises, using the suffix Promise.
385+
promisify: require('util').promisify // Needs Node.js version 8 or greater, see comment below
386+
ifReadOnlySuffix: "_alt"
387+
};
388+
```
389+
390+
* `asyncSuffix` Suffix for callback-based async method call signatures.
391+
* `syncSuffix` Suffix for synchronous method call signatures.
392+
* `promiseSuffix` Suffix for promise-based async method call signatures
393+
* `promisify` Callback-to-promise transform implementation. From Node.js version 8 one can just use Node.js implementation: `promisify: require('util').promisify`.
394+
* `ifReadOnlySuffix` See [Static Member Name Conflicts](#staticMemberNameConflicts).
395+
396+
See [Async Options](#asyncOptions) for details.
397+
398+
## import
399+
373400
<a name="javaImport" >
374401

375402
*java.import(className)**
376403

377-
Loads the class given by className such that it acts and feels like a javascript object.
404+
Loads the class given by className such that it acts and feels like a JavaScript object.
378405

379406
__Arguments__
380407

@@ -391,6 +418,8 @@ __Example__
391418
var test = new Test();
392419
list.instanceMethodSync('item1');
393420

421+
## newInstance
422+
394423
<a name="javaNewInstance" >
395424

396425
*java.newInstance(className, [args...], callback)**
@@ -414,6 +443,8 @@ __Example__
414443
// new list
415444
});
416445

446+
## instanceOf
447+
417448
<a name="javaInstanceOf" >
418449

419450
*java.instanceOf(javaObject, className)**
@@ -433,6 +464,8 @@ __Example__
433464
console.log("obj is an instance of SuperClass");
434465
}
435466

467+
## callStaticMethod
468+
436469
<a name="javaCallStaticMethod" >
437470

438471
*java.callStaticMethod(className, methodName, [args...], callback)**
@@ -457,6 +490,8 @@ __Example__
457490
// results from doSomething
458491
});
459492

493+
## callMethod
494+
460495
<a name="javaCallMethod" >
461496

462497
*java.callMethod(instance, methodName, [args...], callback)**
@@ -483,6 +518,8 @@ __Example__
483518
// results from doSomething
484519
});
485520

521+
## getStaticFieldValue
522+
486523
<a name="javaGetStaticFieldValue" >
487524

488525
*java.getStaticFieldValue(className, fieldName)**
@@ -498,6 +535,8 @@ __Example__
498535

499536
var data = java.getStaticFieldValue("com.nearinfinty.MyClass", "data");
500537

538+
## setStaticFieldValue
539+
501540
<a name="javaSetStaticFieldValue" >
502541

503542
*java.setStaticFieldValue(className, fieldName, newValue)**
@@ -514,6 +553,8 @@ __Example__
514553

515554
java.setStaticFieldValue("com.nearinfinty.MyClass", "data", "Hello World");
516555

556+
## newArray
557+
517558
<a name="javaNewArray" >
518559

519560
*java.newArray(className, values[])**
@@ -529,6 +570,8 @@ __Example__
529570

530571
var newArray = java.newArray("java.lang.String", ["item1", "item2", "item3"]);
531572

573+
## newByte
574+
532575
<a name="javaNewByte" >
533576

534577
*java.newByte(val)**
@@ -543,6 +586,8 @@ __Example__
543586

544587
var b = java.newByte(12);
545588

589+
## newShort
590+
546591
<a name="javaNewShort" >
547592

548593
*java.newShort(val)**
@@ -557,6 +602,8 @@ __Example__
557602

558603
var s = java.newShort(12);
559604

605+
## newLong
606+
560607
<a name="javaNewLong" >
561608

562609
*java.newLong(val)**
@@ -571,6 +618,8 @@ __Example__
571618

572619
var s = java.newLong(12);
573620

621+
## newChar
622+
574623
<a name="javaNewChar" >
575624

576625
*java.newChar(val)**
@@ -585,6 +634,8 @@ __Example__
585634

586635
var ch = java.newChar('a');
587636

637+
## newDouble
638+
588639
<a name="javaNewDouble" >
589640

590641
*java.newDouble(val)**
@@ -599,6 +650,8 @@ __Example__
599650

600651
var d = java.newDouble(3.14);
601652

653+
## newFloat
654+
602655
<a name="javaNewFloat" >
603656

604657
*java.newFloat(val)**
@@ -613,6 +666,8 @@ __Example__
613666

614667
var f = java.newFloat(3.14);
615668

669+
## newProxy
670+
616671
<a name="javaNewProxy" >
617672

618673
*java.newProxy(interfaceName, functions)**
@@ -639,24 +694,32 @@ __Example__
639694
var thread = java.newInstanceSync("java.lang.Thread", myProxy);
640695
thread.start();
641696

697+
## isJvmCreated
698+
642699
<a name="javaisJvmCreated" >
643700

644701
*java.isJvmCreated()**
645702

646703
Returns true if the JVM has been created. The JVM can only be created once.
647704

705+
## registerClient
706+
648707
<a name="javaRegisterClient" >
649708

650709
*java.registerClient(before, after)**
651710

652711
Register that a client wants to be called back immediately before and/or immediately after the JVM is created. If used, this function must be called before the JVM has been created. The before function is typically used to add to the classpath. The function may execute asynchronous operations (such as a async glob function). The after function is sometimes useful for doing one-time initialization that requires the JVM to first be initialized. If either function is unnecessary, use `null` or `undefined`. See also `registerClientP` and `ensureJvm`. See the unit tests in `testAsyncOptions` for examples.
653712

713+
## registerClientP
714+
654715
<a name="javaRegisterClientP" >
655716

656717
*java.registerClientP(before, after)**
657718

658719
Like java.registerClient, but before and after are assumed to be functions returning promises.
659720

721+
## ensureJvm
722+
660723
<a name="javaEnsureJvm" >
661724

662725
*java.ensureJvm(callback)**
@@ -667,7 +730,9 @@ If the JVM has not yet been created, execute the full JVM initialization process
667730

668731
<a name="javaObject">
669732

670-
# java object
733+
# `java` object
734+
735+
## Call Method
671736

672737
<a name="javaObjectCallMethod" >
673738

@@ -691,6 +756,8 @@ __Example__
691756
if(err) { console.error(err); return; }
692757
});
693758

759+
## Field Access
760+
694761
<a name="javaObjectGetSetField" >
695762

696763
*obj._fieldName_ = val**
@@ -706,9 +773,9 @@ __Example__
706773
list.data = "test";
707774
var data = list.data;
708775

709-
<a name="getFullMethodSignature" >
776+
## Getting the Full Method Signature
710777

711-
Getting the Full Method Signature
778+
<a name="getFullMethodSignature" >
712779

713780
Run `javap -s -classpath <your-class-path> <your-class-name>`. Find the method name you are looking for. For example:
714781

@@ -772,9 +839,12 @@ ShutdownHookHelper.setShutdownHookSync(java.newProxy('java.lang.Runnable', {
772839

773840
When you call a Java method through node-java, any arguments (V8/JavaScript objects) will be converted to Java objects on the v8 main thread via a call to v8ToJava (found in utils.cpp). The JavaScript object is not held on to and can be garbage collected by v8. If this is an async call, the reference count on the Java objects will be incremented. The Java method will be invoked in a node.js async thread (see uv_queue_work). When the method returns, the resulting object will be returned to the main v8 thread and converted to JavaScript objects via a call to javaToV8 and the Java object's reference count will then be decremented to allow for garbage collection. The resulting v8 object will then be returned to the callers callback function.
774841

842+
843+
<a name="staticMemberNameConflicts" >
844+
775845
# Static member name conflicts ('name', 'arguments', 'caller')
776846

777-
The JavaScript object returned by `java.import(classname)` is a Javascript constructor Function, implemented such that you can create instances of the Java class. For example:
847+
The JavaScript object returned by `java.import(classname)` is a JavaScript constructor Function, implemented such that you can create instances of the Java class. For example:
778848

779849
```javascript
780850
var Test = java.import('Test');
@@ -785,7 +855,7 @@ Test.someStaticMethod(function(err, result) { ... });
785855
var value1 = Test.NestedEnum.Value1;
786856
```
787857

788-
But Javascript reserves a few property names of Function objects: `name`, `arguments`, and `caller`. If your class has public static members (either methods or fields) with these names, node-java is unable to create the necessary property to implement the class's API. For example, suppose your class `Test` implements a static method named `caller`, or has a `NestedEnum` with a value `name`:
858+
But JavaScript reserves a few property names of Function objects: `name`, `arguments`, and `caller`. If your class has public static members (either methods or fields) with these names, node-java is unable to create the necessary property to implement the class's API. For example, suppose your class `Test` implements a static method named `caller`, or has a `NestedEnum` with a value `name`:
789859

790860
```java
791861
public class Test {
@@ -795,7 +865,7 @@ public class Test {
795865
}
796866
```
797867

798-
In Javascript, you would expect to be able to use those static members like this:
868+
In JavaScript, you would expect to be able to use those static members like this:
799869

800870
```javascript
801871
var Test = java.import('Test');

0 commit comments

Comments
 (0)