
Security News
Axios Supply Chain Attack Reaches OpenAI macOS Signing Pipeline, Forces Certificate Rotation
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.
java-js-node
Advanced tools
A Node.js module to run Java JAR files from URLs or local paths with enhanced features
An advanced Node.js module for running Java JAR files from local paths or URLs with advanced JRE auto-download features, intelligent caching, and automatic validation.
npm install java-js-node
const { runJar } = require('java-js-node');
// Run a local JAR
const result = await runJar('./test/helloworld-1.0.0-SNAPSHOT.jar');
console.log('Exit code:', result.exitCode);
console.log('Output:', result.stdout);
const { runJar } = require('java-js-node');
// Basic execution with security validation
async function helloWorld() {
// ✅ JAR validation mandatory for security
const isValid = await runJar.validateJar('./test/helloworld-1.0.0-SNAPSHOT.jar');
if (!isValid) {
throw new Error('JAR unsafe or corrupted');
}
const result = await runJar('./test/helloworld-1.0-SNAPSHOT.jar');
console.log('Exit code:', result.exitCode);
console.log('Output:', result.stdout);
}
const { runJar } = require('java-js-node');
async function runWithArgs() {
// Run JAR with configuration parameters
const result = await runJar('./my-app.jar', ['--config', 'dev.json', '--debug']);
console.log('Application executed with code:', result.exitCode);
}
const { runJar } = require('java-js-node');
async function startSpringApp() {
console.log('🚀 Starting Spring Boot application...');
// ✅ Mandatory validation before execution
const isValid = await runJar.validateJar('./target/spring-app.jar');
if (!isValid) {
throw new Error('Invalid Spring Boot JAR');
}
// Run with production configuration
const result = await runJar('./target/spring-app.jar', [
'--spring.profiles.active=prod',
'--server.port=8080'
]);
if (result.exitCode === 0) {
console.log('✅ Spring Boot started successfully');
} else {
console.error('❌ Startup error:', result.stderr);
}
}
const { runJar } = require('java-js-node');
async function processBatch() {
// ✅ Always validate before execution
const isValid = await runJar.validateJar('./batch-processor.jar');
if (!isValid) {
throw new Error('Invalid processor JAR');
}
// Process files with specific parameters
const result = await runJar('./batch-processor.jar', [
'--input', './data/input.csv',
'--output', './data/output.csv',
'--batch-size', '1000'
]);
console.log('Batch completed with exit code:', result.exitCode);
}
const { create } = require('java-js-node');
async function sequentialExecution() {
const runner = create({ debug: true });
const jars = [
{ path: './init-database.jar', args: ['--setup'] },
{ path: './load-data.jar', args: ['--import'] },
{ path: './process-data.jar', args: ['--transform'] },
{ path: './cleanup.jar', args: ['--finalize'] }
];
for (const jar of jars) {
console.log(`Executing: ${jar.path}`);
// ✅ Validation for each JAR
const isValid = await runner.validateJar(jar.path);
if (!isValid) {
throw new Error(`Invalid JAR ${jar.path}`);
}
const result = await runner.runJar(jar.path, jar.args);
if (result.exitCode !== 0) {
throw new Error(`Error in ${jar.path}: ${result.stderr}`);
}
console.log(`✅ ${jar.path} completed`);
}
console.log('🎉 Sequential pipeline completed!');
}
const { create } = require('java-js-node');
async function parallelExecution() {
const runner = create({ debug: true });
const services = [
{ name: 'auth-service', jar: './auth.jar', args: ['--port', '8081'] },
{ name: 'user-service', jar: './users.jar', args: ['--port', '8082'] },
{ name: 'notification-service', jar: './notifications.jar', args: ['--port', '8083'] }
];
console.log('🚀 Starting services in parallel...');
// Execute all services simultaneously
const promises = services.map(async (service) => {
console.log(`Starting ${service.name}...`);
// ✅ Mandatory validation
const isValid = await runner.validateJar(service.jar);
if (!isValid) {
throw new Error(`Invalid ${service.name} JAR`);
}
const result = await runner.runJar(service.jar, service.args);
return { service: service.name, result };
});
try {
const results = await Promise.all(promises);
results.forEach(({ service, result }) => {
if (result.exitCode === 0) {
console.log(`✅ ${service} started successfully`);
} else {
console.error(`❌ Error in ${service}:`, result.stderr);
}
});
} catch (error) {
console.error('Error in parallel startup:', error.message);
}
}
const { create, validateJar } = require('java-js-node');
async function cicdPipeline() {
const runner = create({
debug: true,
jreMajor: 17,
workdir: './build/runtime'
});
const jarPath = './target/application.jar';
console.log('🔄 Starting CI/CD pipeline...\n');
// 1. ✅ Validate built JAR
console.log('1️⃣ JAR validation...');
const isValid = await validateJar(jarPath);
if (!isValid) {
throw new Error('Invalid built JAR - build failed');
}
console.log('✅ JAR valid\n');
// 2. Unit tests
console.log('2️⃣ Running unit tests...');
const testResult = await runner.runJar(jarPath, ['--test', '--unit']);
if (testResult.exitCode !== 0) {
throw new Error('Unit tests failed');
}
console.log('✅ Unit tests passed\n');
// 3. Integration tests
console.log('3️⃣ Running integration tests...');
const integrationResult = await runner.runJar(jarPath, ['--test', '--integration']);
if (integrationResult.exitCode !== 0) {
throw new Error('Integration tests failed');
}
console.log('✅ Integration tests passed\n');
// 4. Deploy to staging
console.log('4️⃣ Deploy to staging environment...');
await runner.runJar(jarPath, ['--deploy', '--env', 'staging']);
console.log('✅ Staging deploy completed\n');
// 5. End-to-end tests
console.log('5️⃣ Running E2E tests...');
const e2eResult = await runner.runJar(jarPath, ['--test', '--e2e']);
if (e2eResult.exitCode !== 0) {
throw new Error('E2E tests failed');
}
console.log('✅ E2E tests passed\n');
console.log('🎉 CI/CD pipeline completed successfully!');
}
const { create, JavaRunnerError } = require('java-js-node');
class ServiceManager {
constructor() {
this.runner = create({
debug: true,
jreMajor: 17
});
this.services = new Map();
}
async startService(name, jarPath, args = []) {
try {
console.log(`🚀 Starting service ${name}...`);
// ✅ Mandatory validation
const isValid = await this.runner.validateJar(jarPath);
if (!isValid) {
throw new JavaRunnerError(`Invalid JAR ${name}`, 'INVALID_JAR');
}
const result = await this.runner.runJar(jarPath, args);
this.services.set(name, { status: 'running', result });
console.log(`✅ Service ${name} started`);
return result;
} catch (error) {
this.services.set(name, { status: 'error', error: error.message });
console.error(`❌ Error starting ${name}:`, error.message);
throw error;
}
}
async stopService(name) {
if (this.services.has(name)) {
this.services.delete(name);
console.log(`🛑 Service ${name} stopped`);
}
}
getStatus() {
return Array.from(this.services.entries()).map(([name, service]) => ({
name,
status: service.status,
exitCode: service.result?.exitCode
}));
}
}
async function manageMicroservices() {
const manager = new ServiceManager();
try {
// Start core services
await manager.startService('auth-service', './auth.jar', ['--port', '8081']);
await manager.startService('user-service', './users.jar', ['--port', '8082']);
await manager.startService('api-gateway', './gateway.jar', ['--port', '8080']);
console.log('\n📊 Service status:');
console.log(manager.getStatus());
} catch (error) {
console.error('\n❌ Error in microservice management:', error.message);
// Cleanup services in case of error
console.log('🧹 Service cleanup...');
await manager.stopService('auth-service');
await manager.stopService('user-service');
await manager.stopService('api-gateway');
}
}
These practical examples show how to use Node Java Runner in real scenarios, from simple JAR execution to complex enterprise pipeline management. Each example follows the project's security rules with mandatory JAR validation and appropriate error handling.
const { create } = require('java-js-node');
// Create an instance with custom options
const runner = create({
workdir: './custom-runtime', // Custom working directory
jreMajor: 17, // Specific Java version
javaPath: '/custom/java/path', // Custom Java path
debug: true // Enable debug logging
});
// Run JAR with arguments
const result = await runner.runJar('./my-app.jar', ['--port', '8080', '--env', 'production']);
// Verify if a file is a valid JAR
const isValid = await runner.validateJar('./app.jar');
if (isValid) {
console.log('✅ Valid JAR');
}
// Check Java installation
const javaInfo = await runner.checkJavaVersion();
console.log(`Java ${javaInfo.version} found at: ${javaInfo.path}`);
Listeners allow you to capture JAR output in real-time during execution, useful for advanced logging, monitoring, and integration with external systems.
const { create } = require('java-js-node');
async function esempioListenerBasico() {
// Create the runner with custom configuration
const runner = create({
debug: true,
jreMajor: 17
});
// Initialize with the correct pattern
await runner.init({
workdir: './runtime',
minimumVersion: 17
});
console.log('🚀 Starting JAR with basic listener...\n');
// Run JAR with listener for real-time logging
const result = await runner.runJar('./test/helloworld-1.0.0-SNAPSHOT.jar', [], {
onStdout: (data) => {
console.log(`📤 STDOUT: ${data.trim()}`);
},
onStderr: (data) => {
console.log(`⚠️ STDERR: ${data.trim()}`);
}
});
console.log(`\n✅ Execution completed - Exit code: ${result.exitCode}`);
}
const { create } = require('java-js-node');
async function esempioListenerAvanzato() {
const runner = create({
debug: true,
jreMajor: 17
});
await runner.init({
workdir: './runtime'
});
const logs = [];
let startTime = Date.now();
console.log('🔍 Starting JAR with advanced listener...\n');
const result = await runner.runJar('./test/helloworld-1.0.0-SNAPSHOT.jar', [], {
onStdout: (data) => {
const timestamp = new Date().toISOString();
const elapsed = ((Date.now() - startTime) / 1000).toFixed(2);
logs.push({ type: 'INFO', timestamp, elapsed, data: data.trim() });
console.log(`[${timestamp}] [${elapsed}s] 📤 ${data.trim()}`);
},
onStderr: (data) => {
const timestamp = new Date().toISOString();
const elapsed = ((Date.now() - startTime) / 1000).toFixed(2);
logs.push({ type: 'ERROR', timestamp, elapsed, data: data.trim() });
console.log(`[${timestamp}] [${elapsed}s] ❌ ${data.trim()}`);
}
});
// Post-execution analysis
const errors = logs.filter(log => log.type === 'ERROR');
const totalTime = ((Date.now() - startTime) / 1000).toFixed(2);
console.log(`\n📊 Execution statistics:`);
console.log(` ⏱️ Total time: ${totalTime}s`);
console.log(` 📝 Total logs: ${logs.length}`);
console.log(` ❌ Errors: ${errors.length}`);
console.log(` ✅ Exit code: ${result.exitCode}`);
}
const { create } = require('java-js-node');
const fs = require('fs').promises;
class CustomLogger {
constructor(logFile) {
this.logFile = logFile;
this.startTime = Date.now();
}
async log(level, message) {
const timestamp = new Date().toISOString();
const elapsed = ((Date.now() - this.startTime) / 1000).toFixed(2);
const logEntry = `[${timestamp}] [${elapsed}s] [${level}] ${message}\n`;
console.log(logEntry.trim());
// Save to file
try {
await fs.appendFile(this.logFile, logEntry);
} catch (error) {
console.error(`Error saving log: ${error.message}`);
}
}
info(message) { return this.log('INFO', message); }
error(message) { return this.log('ERROR', message); }
warn(message) { return this.log('WARN', message); }
}
async function esempioIntegrazioneInit() {
const runner = create({
debug: true,
jreMajor: 17
});
// Complete init() pattern with configuration
await runner.init({
workdir: './runtime',
minimumVersion: 17,
jreMajor: 17
});
const logger = new CustomLogger('./logs/app-runtime.log');
console.log('🔧 Starting JAR with custom logger...\n');
const result = await runner.runJar('./test/helloworld-1.0.0-SNAPSHOT.jar', [], {
onStdout: async (data) => {
await logger.info(`Application: ${data.trim()}`);
},
onStderr: async (data) => {
await logger.error(`Application Error: ${data.trim()}`);
}
});
await logger.info(`Execution completed with exit code: ${result.exitCode}`);
console.log(`\n✅ Logs saved in: ./logs/app-runtime.log`);
console.log(`📊 Final exit code: ${result.exitCode}`);
}
const { create } = require('java-js-node');
class PerformanceMonitor {
constructor() {
this.metrics = {
startTime: null,
endTime: null,
memoryUsage: [],
cpuUsage: [],
logCount: 0,
errorCount: 0
};
}
start() {
this.metrics.startTime = Date.now();
console.log('📊 Performance monitoring started');
}
recordMemory() {
const usage = process.memoryUsage();
this.metrics.memoryUsage.push({
timestamp: Date.now(),
rss: Math.round(usage.rss / 1024 / 1024), // MB
heapUsed: Math.round(usage.heapUsed / 1024 / 1024) // MB
});
}
log(type, data) {
this.metrics.logCount++;
if (type === 'ERROR') {
this.metrics.errorCount++;
}
const elapsed = this.metrics.startTime ?
((Date.now() - this.metrics.startTime) / 1000).toFixed(2) : '0.00';
console.log(`[${elapsed}s] ${type === 'ERROR' ? '❌' : '📤'} ${data.trim()}`);
}
end() {
this.metrics.endTime = Date.now();
this.printReport();
}
printReport() {
const totalTime = ((this.metrics.endTime - this.metrics.startTime) / 1000).toFixed(2);
const avgMemory = this.metrics.memoryUsage.length > 0 ?
Math.round(this.metrics.memoryUsage.reduce((sum, m) => sum + m.heapUsed, 0) / this.metrics.memoryUsage.length) : 0;
console.log('\n📊 PERFORMANCE REPORT');
console.log('='.repeat(50));
console.log(`⏱️ Execution time: ${totalTime}s`);
console.log(`📝 Total logs: ${this.metrics.logCount}`);
console.log(`❌ Errors: ${this.metrics.errorCount}`);
console.log(`🧠 Average memory: ${avgMemory} MB`);
console.log(`📊 Memory samples: ${this.metrics.memoryUsage.length}`);
console.log('='.repeat(50));
}
}
async function esempioMonitoraggioPerformance() {
const runner = create({
debug: true,
jreMajor: 17
});
// Optimized init() pattern with configuration
await runner.init({
workdir: './runtime',
minimumVersion: 17
});
const monitor = new PerformanceMonitor();
monitor.start();
// Interval for memory sampling every 500ms
const memoryInterval = setInterval(() => {
monitor.recordMemory();
}, 500);
console.log('⚡ Starting JAR with performance monitoring...\n');
const result = await runner.runJar('./test/helloworld-1.0.0-SNAPSHOT.jar', [], {
onStdout: (data) => monitor.log('INFO', data),
onStderr: (data) => monitor.log('ERROR', data)
});
clearInterval(memoryInterval);
monitor.end();
console.log(`\n🎯 Exit code: ${result.exitCode}`);
console.log(`📈 Detailed metrics available in monitor.metrics`);
}
These examples show how to use listeners for:
Listeners are particularly useful for applications that require continuous monitoring, advanced debugging, or integration with enterprise logging systems.
runJar(jarPath, args = [])Executes a JAR file with the specified arguments.
Parameters:
jarPath (string): Path to the JAR file (local or URL)args (string[]): Array of arguments to pass to the JARReturns: Promise<Object>
{
stdout: string, // Standard output
stderr: string, // Standard errors
exitCode: number // Process exit code
}
Example:
const result = await runJar('./my-app.jar', ['--config', 'prod.json']);
validateJar(jarPath)Validates if a file is a valid JAR.
Parameters:
jarPath (string): Path to the JAR fileReturns: Promise<boolean>
Example:
const isValid = await validateJar('./application.jar');
findJavaPath()Finds the path to the Java executable in the system.
Returns: Promise<string|null>
Example:
const javaPath = await findJavaPath();
if (javaPath) {
console.log('Java found at:', javaPath);
}
checkJavaVersion()Checks the installed Java version.
Returns: Promise<Object>
{
path: string, // Path to Java executable
version: string, // Java version
available: boolean // Availability
}
Example:
const info = await checkJavaVersion();
console.log(`Java ${info.version} at ${info.path}`);
constructor(options = {})Creates a new NodeJavaRunner instance.
Options:
workdir (string): Working directory for downloads and cache (default: ./runtime)jreMajor (number): Major Java version to use (default: 17)javaPath (string): Custom path to Java executabledebug (boolean): Enable debug logging (default: false)runJar(jarPath, args = [])Executes a JAR file with the specified arguments.
validateJar(jarPath)Validates a JAR file.
findJavaPath()Finds the Java path in the system.
checkJavaVersion()Checks the Java version.
The module supports the following environment variables for configuration:
| Variable | Description | Default |
|---|---|---|
JAVA_JS_NODE_WORKDIR | Custom working directory | ./runtime |
JAVA_JS_NODE_JRE_MAJOR | Major Java version | 17 |
JAVA_JS_NODE_DEBUG | Enable debug logging | false |
JAVA_HOME | Custom Java installation directory | - |
# Configuration via environment variables
export JAVA_JS_NODE_DEBUG=true
export JAVA_JS_NODE_WORKDIR=/tmp/java-js-node
export JAVA_JS_NODE_JRE_MAJOR=11
export JAVA_HOME=/opt/jdk-17
node my-app.js
Problem: The system cannot find Java.
Solutions:
Install Java manually:
# Ubuntu/Debian
sudo apt-get install openjdk-17-jre
# CentOS/RHEL
sudo yum install java-17-openjdk
# macOS
brew install openjdk@17
# Windows (using Chocolatey)
choco install openjdk17
Set JAVA_HOME:
export JAVA_HOME=/path/to/java
Use custom configuration:
const runner = create({
javaPath: '/custom/java/path'
});
Problem: The specified file is not a valid JAR.
Solutions:
.jar extensionconst isValid = await validateJar('./app.jar');
if (!isValid) {
throw new Error('Invalid JAR');
}
Problem: JRE download failed due to lack of space.
Solutions:
const runner = create({
workdir: '/path/with/more/space'
});
Problem: Unable to download or extract JRE.
Solutions:
const runner = create({
workdir: process.env.HOME + '/java-runner'
});
const { runJar } = require('java-js-node');
async function startRemoteServer() {
try {
// Download and run JAR from URL
const result = await runJar('https://example.com/app.jar', ['--server', '--port', '3000']);
if (result.exitCode === 0) {
console.log('Server started successfully');
console.log(result.stdout);
} else {
console.error('Server startup error:', result.stderr);
}
} catch (error) {
console.error('Error:', error.message);
}
}
const { create, validateJar } = require('java-js-node');
async function deployApplication() {
const runner = create({
debug: true,
jreMajor: 17,
workdir: './build/runtime'
});
// 1. Validate the built JAR
const jarPath = './target/app-1.0.0.jar';
const isValid = await validateJar(jarPath);
if (!isValid) {
throw new Error('Invalid built JAR');
}
// 2. Run integration tests
console.log('Running integration tests...');
const testResult = await runner.runJar(jarPath, ['--test', '--integration']);
if (testResult.exitCode !== 0) {
throw new Error('Integration tests failed');
}
// 3. Deploy to production
console.log('Deploying to production...');
await runner.runJar(jarPath, ['--deploy', '--env', 'prod']);
console.log('Deploy completed successfully!');
}
const { runJar, JavaRunnerError } = require('java-js-node');
async function safeJarExecution() {
try {
const result = await runJar('./app.jar');
if (result.exitCode === 0) {
console.log('Execution completed');
} else {
console.warn(`JAR terminated with code ${result.exitCode}`);
}
} catch (error) {
if (error instanceof JavaRunnerError) {
switch (error.code) {
case 'JAVA_NOT_FOUND':
console.error('Java not installed. Install Java or check JAVA_HOME');
break;
case 'JAR_NOT_FOUND':
console.error('JAR file not found:', error.message);
break;
case 'INVALID_JAR_FORMAT':
console.error('The specified file is not a valid JAR');
break;
default:
console.error('Unknown error:', error.message);
}
} else {
console.error('Unexpected error:', error.message);
}
}
}
Contributions are welcome! Please feel free to submit a Pull Request.
git checkout -b feature/AmazingFeature)git commit -m 'Add some AmazingFeature')git push origin feature/AmazingFeature)This project is distributed under the ISC license.
ISC License
Copyright (c) TND Team
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
If you encounter problems or have questions:
test.jsMade with ❤️ by TND Team
FAQs
A Node.js module to run Java JAR files from URLs or local paths with enhanced features
The npm package java-js-node receives a total of 4 weekly downloads. As such, java-js-node popularity was classified as not popular.
We found that java-js-node demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.

Security News
Open source is under attack because of how much value it creates. It has been the foundation of every major software innovation for the last three decades. This is not the time to walk away from it.

Security News
Socket CEO Feross Aboukhadijeh breaks down how North Korea hijacked Axios and what it means for the future of software supply chain security.