An open API service indexing awesome lists of open source software.

https://github.com/nvuillam/node-java-caller

Lightweight cross-platform javascript module to easily call java from node sources. Automatically install java if not present
https://github.com/nvuillam/node-java-caller

java javascript node spawn

Last synced: 9 months ago
JSON representation

Lightweight cross-platform javascript module to easily call java from node sources. Automatically install java if not present

Awesome Lists containing this project

README

          

# Java Caller for Node.js

[![Version](https://img.shields.io/npm/v/java-caller.svg)](https://www.npmjs.com/package/java-caller)
[![Downloads/week](https://img.shields.io/npm/dw/java-caller.svg)](https://npmjs.org/package/java-caller)
[![Downloads/total](https://img.shields.io/npm/dt/java-caller.svg)](https://npmjs.org/package/java-caller)
[![Generated by github-dependents-info](https://img.shields.io/static/v1?label=Used%20by&message=106&color=informational&logo=slickpic)](https://github.com/nvuillam/node-java-caller/blob/main/docs/github-dependents-info.md)
[![CircleCI](https://circleci.com/gh/nvuillam/node-java-caller/tree/master.svg?style=shield)](https://circleci.com/gh/nvuillam/node-java-caller/tree/master)
[![Mega-Linter](https://github.com/nvuillam/node-java-caller/workflows/Mega-Linter/badge.svg)](https://github.com/nvuillam/mega-linter#readme)
[![codecov](https://codecov.io/gh/nvuillam/node-java-caller/branch/master/graph/badge.svg)](https://codecov.io/gh/nvuillam/node-java-caller)
[![GitHub contributors](https://img.shields.io/github/contributors/nvuillam/node-java-caller.svg)](https://gitHub.com/nvuillam/node-java-caller/graphs/contributors/)
[![GitHub stars](https://img.shields.io/github/stars/nvuillam/node-java-caller?label=Star&maxAge=2592000)](https://GitHub.com/nvuillam/node-java-caller/stargazers/)
[![License](https://img.shields.io/npm/l/java-caller.svg)](https://github.com/nvuillam/node-java-caller/blob/master/LICENSE)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)

Lightweight cross-platform javascript module to **easily call java commands from Node.js sources**.

- **Automatically installs required Java version** if not present on the system
- Compliant with **JDK & JRE** from **8 to 21**
- Uses node [spawn](https://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options) method to perform the call

There are two ways to use java-caller:

- **module**: Manually call JavaCaller in your custom JS/TS code ([example project](https://github.com/nvuillam/node-java-caller/tree/master/examples/module_app))
- **CLI**: Just define a java-caller-config.json and you can deliver your java executables as your own NPM packages ! ([example project](https://github.com/nvuillam/node-java-caller/tree/master/examples/cli_app), which can be used as starter kit)

## Installation

```shell
npm install java-caller --save
```

## Usage

```javascript
const JavaCaller = require('java-caller');
const java = new JavaCaller(JAVA_CALLER_OPTIONS);
const {status, stdout, stderr} = await java.run(JAVA_ARGUMENTS,JAVA_CALLER_RUN_OPTIONS);
```

### JAVA_CALLER_OPTIONS

| Parameter | Description | Default value | Example |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | ---------------------------------------- |
| jar | Path to executable jar file | | `"myfolder/myjar.jar"` |
| classPath | If jar parameter is not set, classpath to use
Use `:` as separator (it will be converted if runned on Windows), or use a string array. | `.` (current folder) | `"java/myJar.jar:java/myOtherJar.jar"` |
| useAbsoluteClassPaths | Set to true if classpaths should not be based on the rootPath | `false` | `true` |
| mainClass | If classPath set, main class to call | | `"com.example.MyClass"` |
| rootPath | If classPath elements are not relative to the current folder, you can define a root path.
You may use `__dirname` if you classes / jars are in your module folder | `.` (current folder) | `"/home/my/folder/containing/jars"` |
| minimumJavaVersion | Minimum java version to be used to call java command.
If the java version found on machine is lower, java-caller will try to install and use the appropriate one | `8` | `11` |
| maximumJavaVersion | Maximum java version to be used to call java command.
If the java version found on machine is upper, java-caller will try to install and use the appropriate one
Can be equal to minimumJavaVersion | | `10` |
| javaType | jre or jdk (if not defined and installation is required, jre will be installed) | | `"jre"` |
| additionalJavaArgs | Additional parameters for JVM that will be added in every JavaCaller instance runs | | `["-Xms256m","-Xmx2048m"]` |
| javaExecutable | You can force to use a defined java executable, instead of letting java-caller find/install one. Can also be defined with env var `JAVA_CALLER_JAVA_EXECUTABLE` | | `"/home/some-java-version/bin/java.exe"` |

### JAVA_ARGUMENTS

The list of arguments can contain both arguments types together:

- Java arguments (**-X***, **-D***). ex: `"-Xms256m"`, `"-Xmx2048m"`
- Main class arguments (sent to `public static void main method`). ex: `"--someflag"` , `"--someflagwithvalue myVal"` , `"-c"`

Example: `["-Xms256m", "--someflagwithvalue myVal", "-c"]`

### JAVA_CALLER_RUN_OPTIONS

| Parameter | Description | Default | Example |
|-----------|-------------|---------|---------|
| [detached](https://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options) | If set to true, node will node wait for the java command to be completed.
In that case, `childJavaProcess` property will be returned, but `stdout` and `stderr` may be empty, except if an error is triggered at command execution | `false` | `true`
| [stdoutEncoding](https://nodejs.org/api/stream.html#readablesetencodingencoding) | Adds control on spawn process stdout | `utf8` | `ucs2` |
| waitForErrorMs | If detached is true, number of milliseconds to wait to detect an error before exiting JavaCaller run | `500` | `2000` |
| [cwd](https://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options) | You can override cwd of spawn called by JavaCaller runner | `process.cwd()` | `some/other/cwd/folder` |
| javaArgs | List of arguments for JVM only, not the JAR or the class | `[]` | `['--add-opens=java.base/java.lang=ALL-UNNAMED']` |
| [windowsVerbatimArguments](https://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options) | No quoting or escaping of arguments is done on Windows. Ignored on Unix. This is set to true automatically when shell is specified and is CMD. | `true` | `false` |
| [windowless](https://docs.oracle.com/en/java/javase/17/docs/specs/man/java.html#:~:text=main()%20method.-,javaw,information%20if%20a%20launch%20fails.) | If windowless is true, JavaCaller calls javaw instead of java to not create any windows, useful when using detached on Windows. Ignored on Unix. | false | true

## Examples

Call a class located in classpath

```javascript
const java = new JavaCaller({
classPath: 'test/java/dist',
mainClass: 'com.nvuillam.javacaller.JavaCallerTester'
});
const { status, stdout, stderr } = await java.run();
```

Call a class with multiple folders in the classPath

```javascript
const java = new JavaCaller({
classPath: ['C:\\pathA\\test\\java\\dist', 'C:\\pathB\\test\\java\\dist'],
mainClass: 'com.nvuillam.javacaller.JavaCallerTester'
});
const { status, stdout, stderr } = await java.run();
```

Call a class located in classpath with java and custom arguments

```javascript
const java = new JavaCaller({
classPath: 'test/java/dist',
mainClass: 'com.nvuillam.javacaller.JavaCallerTester'
});
const { status, stdout, stderr } = await java.run(['-Xms256m', '-Xmx2048m', '--customarg nico']);
```

Call a class in jar located in classpath

```javascript
const java = new JavaCaller({
classPath: 'test/java/jar/JavaCallerTester.jar',
mainClass: 'com.nvuillam.javacaller.JavaCallerTester'
});
const { status, stdout, stderr } = await java.run();
```

Call a runnable jar

```javascript
const java = new JavaCaller({
jar: 'test/java/jar/JavaCallerTesterRunnable.jar',
});
const { status, stdout, stderr } = await java.run();
```

Call a detached java process

```javascript
const java = new JavaCaller({
classPath: 'test/java/dist',
mainClass: 'com.nvuillam.javacaller.JavaCallerTester'
});
const { status, stdout, stderr, childJavaProcess } = await java.run(['--sleep'], { detached: true });

// Kill later the java process if necessary
childJavaProcess.kill('SIGINT');
```

Call a windowless java process

```javascript
const java = new JavaCaller({
classPath: 'test/java/dist',
mainClass: 'com.nvuillam.javacaller.JavaCallerTester'
});
const { status, stdout, stderr } = await java.run(['--sleep'], { windowless: true });
```

You can see **more examples in** [**test methods**](https://github.com/nvuillam/node-java-caller/blob/master/test/java-caller.test.js)

## TROUBLESHOOTING

Set environment variable `DEBUG=java-caller` before calling your code using java-caller module, and you will see the java commands executed.

Example debug log:

```shell
java-caller Found Java version 1.80131 +1s
java-caller Java command: java -Xms256m -Xmx2048m -cp C:\Work\gitPerso\node-java-caller\test\java\dist com.nvuillam.javacaller.JavaCallerTester -customarg nico +1ms
```

## CONTRIBUTE

Contributions are very welcome !

Please follow [Contribution instructions](CONTRIBUTING.md)

## RELEASE NOTES

See complete [CHANGELOG](CHANGELOG.md)