Node.js Nailgun Client
node-nailgun-client provides a Node.js API and command-line interface (CLI) for interacting with a Nailgun server. Nailgun is a system designed to run Java programs from the command line without incurring the typical JVM startup overhead, acting as a long-running JVM server that executes commands sent from a client. This package allows Node.js applications to programmatically execute Java code via the Nailgun protocol. The current and only stable version is 0.1.2, last published over seven years ago. The package's development is abandoned, coinciding with the upstream Nailgun project itself being officially unmaintained since April 2023. Key differentiators included its attempt to integrate high-performance Java execution within Node.js workflows by leveraging Nailgun's persistent JVM model.
Common errors
-
require is not defined in ES module scope
cause Attempting to use `require('node-nailgun-client')` in an ECMAScript Module (ESM) context where `require` is not globally available.fixEnsure your Node.js file or project is running as CommonJS. For example, rename your file to `.cjs` or ensure your `package.json` does not have `"type": "module"` set. If you must use ESM, you can try dynamic `import()`: `const nailgunClient = await import('node-nailgun-client');` but full compatibility is not guaranteed. -
Error: connect ECONNREFUSED <address>:<port>
cause The Nailgun client attempted to connect to a server at the specified address and port, but no server was listening or the connection was actively refused.fixVerify that your Nailgun server is running and listening on the correct IP address and port. Check firewall rules that might be blocking the connection. Ensure the `address` and `port` options passed to `nailgunClient.exec` match your server configuration. -
Failed to read nailgun output after X seconds!
cause The Nailgun client connected to the server, but the invoked Nailgun process failed to produce output or respond within the expected timeout period, often indicating the Java program itself crashed or failed to start correctly on the server.fixCheck the Nailgun server's logs (often found in `.pants.d/ng/<tool-name>/{stdout,stderr}` if used with a build system like Pants). Temporarily disabling Nailgun (if your build system supports it) can also force the underlying command to run directly, revealing the actual error message. Ensure the Java class path and arguments are correct for the command being executed. -
java.net.SocketException: Connection reset
cause The connection to the Nailgun server was abruptly terminated, often because the server crashed, was shut down unexpectedly, or an intermediary network device closed the connection.fixExamine the Nailgun server's logs for crashes or error messages. Ensure the server has sufficient resources (memory, CPU) and is stable. Check for network instability or server-side configuration issues that might cause premature connection closure.
Warnings
- breaking The `node-nailgun-client` package is abandoned, with its last publish over 7 years ago. The upstream Nailgun project itself was declared unmaintained in April 2023. This means there will be no further updates, bug fixes, or security patches, making it unsuitable for new projects or production use.
- breaking The original Nailgun protocol and server are explicitly noted as 'not secure.' They lack robust user authentication or authorization, allowing any program executed on the server to run with the same permissions as the Nailgun server process itself. This poses a significant security risk if exposed.
- gotcha This package is designed for Node.js environments and uses CommonJS `require()`. It does not support modern ECMAScript Modules (ESM) `import` syntax, which can lead to errors like 'require is not defined' in ESM-only contexts.
- gotcha Due to its age (published January 2019), `node-nailgun-client` may have compatibility issues with newer Node.js versions (e.g., Node.js 16, 18, 20+), particularly concerning stream APIs, internal module changes, or underlying system calls, potentially leading to unexpected behavior or crashes.
Install
-
npm install node-nailgun-client -
yarn add node-nailgun-client -
pnpm add node-nailgun-client
Imports
- nailgunClient
import nailgunClient from 'node-nailgun-client';
const nailgunClient = require('node-nailgun-client'); - exec
const { exec } = require('node-nailgun-client');const nail = nailgunClient.exec('command-name', args, options);
Quickstart
const nailgunClient = require('node-nailgun-client');
// Basic execution of a Nailgun command (e.g., 'ng-stats' for server status)
const simpleNail = nailgunClient.exec('ng-stats');
simpleNail.stdout.pipe(process.stdout);
simpleNail.stderr.pipe(process.stderr);
simpleNail.on('exit', (code) => {
if (code !== 0) {
console.error(`ng-stats exited with code ${code}`);
}
});
// Executing a custom Java class with arguments and explicit server options
const options = {
address: 'localhost',
port: 2113
};
const args = ['hello', 'world'];
const customNail = nailgunClient.exec('com.example.MyJavaClass', args, options);
customNail.stdout.pipe(process.stdout); // Pipe Java's stdout to Node's stdout
customNail.stderr.pipe(process.stderr); // Pipe Java's stderr to Node's stderr
// Optionally pipe Node's stdin to Java's stdin if the Java program expects input
// process.stdin.pipe(customNail.stdin);
customNail.on('exit', (code) => {
console.log(`Java program exited with code ${code}`);
// process.exit(code); // Uncomment to exit Node.js with the Java program's exit code
});