java-bridge 2.1.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +251 -0
- package/dist/index.dev.min.js +1107 -0
- package/dist/index.prod.min.js +2 -0
- package/dist/java-ts-gen.js +3 -0
- package/java-src/build/libs/JavaBridge-1.0-SNAPSHOT.jar +0 -0
- package/package.json +104 -0
- package/ts-src/TypescriptDefinitionGenerator.ts +600 -0
- package/ts-src/definitions.ts +210 -0
- package/ts-src/index.ts +24 -0
- package/ts-src/java.ts +676 -0
- package/ts-src/nativeLib.ts +86 -0
- package/ts-src/scripts/cli.ts +142 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 MarkusJx
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
A bridge between Node.js programs and Java APIs written in Rust using [napi-rs](https://napi.rs/)
|
|
2
|
+
to provide a fast and memory-safe interface between the two languages.
|
|
3
|
+
|
|
4
|
+
The pre-compiled binaries will be provided with the package, the only thing
|
|
5
|
+
you need to do on your machine is install a Java Runtime Environment (JRE)
|
|
6
|
+
for this package to use. In contrast to other `node.js <-> java` interfaces,
|
|
7
|
+
the binary is not hard linked to the JDK it has been compiled with but rather
|
|
8
|
+
loads the jvm native library dynamically when the program first starts up.
|
|
9
|
+
|
|
10
|
+
The full documentation of this package is available [here](https://markusjx.github.io/node-java-bridge/).
|
|
11
|
+
|
|
12
|
+
**NOTE: As of version `2.1.0`, this package has been renamed from `@markusjx/java` to `java-bridge`.**
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```shell
|
|
17
|
+
npm i java-bridge
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
### Create the JVM
|
|
23
|
+
|
|
24
|
+
Create a new Java VM using the [`ensureJvm`](https://markusjx.github.io/node-java-bridge/functions/ensureJvm.html) method.
|
|
25
|
+
Calling this after the jvm has already been created will do nothing.
|
|
26
|
+
Destroying the jvm manually is not (yet) supported.
|
|
27
|
+
|
|
28
|
+
#### Create the JVM with no extra options
|
|
29
|
+
|
|
30
|
+
This will first search for a suitable `jvm` native library on the system and then
|
|
31
|
+
start the jvm with no extra options. This is also called when any call to the jvm is made
|
|
32
|
+
but the jvm is not yet started.
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
import { ensureJvm } from 'java-bridge';
|
|
36
|
+
|
|
37
|
+
ensureJvm();
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
#### Create the JVM with extra options
|
|
41
|
+
|
|
42
|
+
You can pass extra options to the jvm when creating it, for example requesting a specific jvm version,
|
|
43
|
+
specifying the location of the jvm native library or passing additional arguments to the jvm.
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
import { ensureJvm, JavaVersion } from 'java-bridge';
|
|
47
|
+
|
|
48
|
+
ensureJvm({
|
|
49
|
+
libPath: 'path/to/jvm.dll',
|
|
50
|
+
version: JavaVersion.VER_9,
|
|
51
|
+
opts: '-Xms512m -Xmx512m',
|
|
52
|
+
});
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
#### Use daemon threads
|
|
56
|
+
|
|
57
|
+
By default, new threads will **not** be attached as daemon threads, meaning any thread attached to the
|
|
58
|
+
jvm will be automatically detached once it is not required anymore. This slows down asynchronous calls
|
|
59
|
+
but will prevent the jvm from being terminated if any thread is still running.
|
|
60
|
+
|
|
61
|
+
If you want to change this behaviour, you can pass the `useDaemonThreads` option to the `ensureJvm` function.
|
|
62
|
+
This will make the jvm attach threads as daemon threads causing those threads to not be detached
|
|
63
|
+
once not required anymore.
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
ensureJvm({
|
|
67
|
+
useDaemonThreads: true,
|
|
68
|
+
});
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Inject a JAR into the class path
|
|
72
|
+
|
|
73
|
+
In order to import your own classes into the node environment, you need
|
|
74
|
+
to add the JAR file to the class path. You can do that with the
|
|
75
|
+
[`appendClasspath`](https://markusjx.github.io/node-java-bridge/functions/appendClasspath.html)
|
|
76
|
+
or [`classpath.append`](https://markusjx.github.io/node-java-bridge/functions/classpath.append.html)
|
|
77
|
+
methods. After loading a JAR, you can import classes from it like any other class
|
|
78
|
+
from the JVM using [`importClass`](#synchronous-calls) or [`importClassAsync`](#asynchronous-calls).
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
import { appendClasspath } from 'java-bridge';
|
|
82
|
+
|
|
83
|
+
// Append a single jar to the class path
|
|
84
|
+
appendClasspath('/path/to/jar.jar');
|
|
85
|
+
|
|
86
|
+
// Append multiple jars to the class path
|
|
87
|
+
appendClasspath(['/path/to/jar1.jar', '/path/to/jar2.jar']);
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
or
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
import { classpath } from 'java-bridge';
|
|
94
|
+
|
|
95
|
+
// Append a single jar to the class path
|
|
96
|
+
classpath.append('/path/to/jar.jar');
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Synchronous calls
|
|
100
|
+
|
|
101
|
+
If you want to use Java APIs in a synchronous way, you can use the synchronous API of this module.
|
|
102
|
+
Any call to the Java API will be executed in the same thread as your node process so this
|
|
103
|
+
may cause your program to hang until the execution is finished. But - in contrast to the asynchronous API -
|
|
104
|
+
these calls are a lot faster as no extra threads need to be created/attached to the JVM.
|
|
105
|
+
|
|
106
|
+
All synchronous java methods are proceeded with the postfix `Sync`.
|
|
107
|
+
This means, all methods of a class (static and non-static) are generated twice,
|
|
108
|
+
once as a synchronous call and once as an asynchronous call.
|
|
109
|
+
|
|
110
|
+
If you are looking for asynchronous calls, take a look at the next section.
|
|
111
|
+
In order to import a class synchronously, you can use the [`importClass`](https://markusjx.github.io/node-java-bridge/functions/importClass.html) function.
|
|
112
|
+
Using this method does not affect your ability to call any method of the class asynchronously.
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
import { importClass } from 'java-bridge';
|
|
116
|
+
|
|
117
|
+
// Import a class
|
|
118
|
+
const JString = importClass('java.lang.String');
|
|
119
|
+
|
|
120
|
+
// Create a new instance of the class
|
|
121
|
+
const str = new JString('Hello World');
|
|
122
|
+
|
|
123
|
+
// Call a method on the instance
|
|
124
|
+
str.lengthSync(); // 11
|
|
125
|
+
|
|
126
|
+
// Supported native types will be automatically converted
|
|
127
|
+
// to the corresponding type in the other language
|
|
128
|
+
str.toStringSync(); // 'Hello World'
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Asynchronous calls
|
|
132
|
+
|
|
133
|
+
If you want to use Java APIs in an asynchronous way, you can use the asynchronous API of this module.
|
|
134
|
+
Any call to the Java API will be executed in a separate thread and the execution will not block your program.
|
|
135
|
+
This is in general a lot slower as the synchronous API but allows the program to run more smoothly.
|
|
136
|
+
|
|
137
|
+
If you want to improve the performance of the asynchronous API, you can force the module to attach
|
|
138
|
+
any thread as a daemon thread to the JVM. This allows the program to not constantly attach new threads
|
|
139
|
+
to the JVM as the old ones can be reused and thus improves the performance.
|
|
140
|
+
|
|
141
|
+
In order to import a class asynchronously, you can use the
|
|
142
|
+
[`importClassAsync`](https://markusjx.github.io/node-java-bridge/functions/importClassAsync.html) function.
|
|
143
|
+
|
|
144
|
+
```ts
|
|
145
|
+
import { importClassAsync } from 'java-bridge';
|
|
146
|
+
|
|
147
|
+
const JString = await importClassAsync('java.lang.String');
|
|
148
|
+
|
|
149
|
+
// Create a new instance asynchrnously using 'newInstanceAsync'
|
|
150
|
+
const str = await JString.newInstanceAsync('Hello World');
|
|
151
|
+
|
|
152
|
+
// Call methods asynchronously
|
|
153
|
+
await str.length(); // 11
|
|
154
|
+
await str.toString(); // 'Hello World'
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Implement a Java interface
|
|
158
|
+
|
|
159
|
+
You can also implement a Java interface in node.js using the
|
|
160
|
+
[`newProxy`](https://markusjx.github.io/node-java-bridge/functions/newProxy.html) method.
|
|
161
|
+
Please note that when calling a java method that uses an interface defined by this method,
|
|
162
|
+
you must call that method using the interface asynchronously as Node.js is single threaded
|
|
163
|
+
and can't wait for the java method to return while calling the proxy method at the same time.
|
|
164
|
+
|
|
165
|
+
```ts
|
|
166
|
+
import { newProxy } from 'java-bridge';
|
|
167
|
+
|
|
168
|
+
const proxy = newProxy('path.to.MyInterface', {
|
|
169
|
+
// Define methods...
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
// Do something with the proxy
|
|
173
|
+
instance.someMethod(proxy);
|
|
174
|
+
|
|
175
|
+
// Destroy the proxy
|
|
176
|
+
proxy.reset();
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Redirect the stdout and stderr from the java process
|
|
180
|
+
|
|
181
|
+
If you want to redirect the stdout and/or stderr from the java
|
|
182
|
+
process to the node.js process, you can use the
|
|
183
|
+
[`enableRedirect`](https://markusjx.github.io/node-java-bridge/functions/stdout.enableRedirect.html)
|
|
184
|
+
method.
|
|
185
|
+
|
|
186
|
+
```ts
|
|
187
|
+
import { stdout } from 'java-bridge';
|
|
188
|
+
|
|
189
|
+
const guard = stdout.enableRedirect(
|
|
190
|
+
(_, data) => {
|
|
191
|
+
console.log('Stdout:', data);
|
|
192
|
+
},
|
|
193
|
+
(_, data) => {
|
|
194
|
+
console.error('Stderr:', data);
|
|
195
|
+
}
|
|
196
|
+
);
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## Value conversion rules
|
|
200
|
+
|
|
201
|
+
1. Any basic value such as `string`, `number`, `boolean` or `BigInt` may be passed to methods accepting matching
|
|
202
|
+
types
|
|
203
|
+
2. `string` values will always be converted to `java.lang.String`
|
|
204
|
+
3. `string` values with just one character may be converted to `char` or `java.lang.Char` if required
|
|
205
|
+
4. Thus, in order to pass a `char` to a java method, use a `string` containing just one character
|
|
206
|
+
5. `number` values will be converted to `int`, `long`, `double`, `float`, `java.lang.Integer`,
|
|
207
|
+
`java.lang.Long`, `java.lang.Double` or `java.lang.Float` depending on the type the java function to call requires
|
|
208
|
+
6. `boolean` values will be converted to either `boolean` or `java.lang.Boolean`
|
|
209
|
+
7. `BigInt` values will be converted to either `long` or `java.lang.Long`
|
|
210
|
+
8. Arrays will be converted to java arrays. Java arrays may only contain a single value type, therefore the type of
|
|
211
|
+
the first element in the array will be chosen as the array type, empty arrays need no conversions.
|
|
212
|
+
9. `java.lang.String` values will be converted to `string`
|
|
213
|
+
10. `int`, `double`, `float`, `java.lang.Integer`, `java.lang.Double` or `java.lang.Float`
|
|
214
|
+
values will be converted to `number`
|
|
215
|
+
11. `long` or `java.lang.Long` values will always be converted to `BigInt`
|
|
216
|
+
12. `boolean` or `java.lang.Boolean` values will be converted to `boolean`
|
|
217
|
+
13. `char` or `java.lang.Character` values will be converted to `string`
|
|
218
|
+
14. Java arrays will be converted to javascript arrays, applying the rules mentioned above except
|
|
219
|
+
15. Byte arrays will be converted to `Buffer` and vice-versa
|
|
220
|
+
|
|
221
|
+
## Command line interface
|
|
222
|
+
|
|
223
|
+
This module also ships with a command line interface called `java-ts-gen` for creating typescript definitions for Java classes.
|
|
224
|
+
The command line interface will create typescript definitions for all specified classes and their dependencies.
|
|
225
|
+
|
|
226
|
+
### Installation
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
npm install -g java-bridge
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### Usage
|
|
233
|
+
|
|
234
|
+
```
|
|
235
|
+
java-ts-gen <output> <classnames..>
|
|
236
|
+
|
|
237
|
+
Positionals:
|
|
238
|
+
classnames The fully qualified class name(s) to convert [string]
|
|
239
|
+
output The output file [string]
|
|
240
|
+
|
|
241
|
+
Options:
|
|
242
|
+
--help Show help [boolean]
|
|
243
|
+
--version Show version number [boolean]
|
|
244
|
+
--classpath, --cp The classpath to use [string]
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### Notes
|
|
248
|
+
|
|
249
|
+
- The classpath argument can be supplied multiple times to add multiple jars to the classpath
|
|
250
|
+
- Multiple class names can be supplied to generate definitions for multiple classes
|
|
251
|
+
- The generated typescript files will automatically import all classes once the module is loaded.
|