SkillAgentSearch skills...

Trireme

Embed Node.js inside a Java Virtual Machine

Install / Use

/learn @apigee/Trireme
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Trireme

This is a set of libraries for running node.js scripts inside Java.

What is Trireme?

Trireme runs Node.js scripts inside the JVM. This is important because there is a lot of software out there (including our own) that is built in Java and isn't going to get rewritten in JavaScript now or in the future.

Trireme is specifically designed to be embeddable within any Java program. There is a lot of support inside Trireme for this specific case:

  • Many Node.js scripts can run inside a single JVM, subject to memory constraints.
  • Each script is totally isolated from the others -- there is no way for one script to affect the heap of the others.
  • A sandbox is provided that lets the container control how, or if, the script gains access to the filesystem and to the network.
  • The HTTP server implementation is pluggable. An "HTTP Adapter" is supported that allows a container to embed a Node.js script inside an existing HTTP container like a web server or other product. (A sample adapter, built using Netty 4.0, is included.)
  • The sandbox supports a Rhino feature that makes it possible to limit the execution time for a script. With this feature enabled, a script that runs an infinite loop can be terminated after some time.

For a more detailed introduction, see our intro presentation:

So, again, why would I use Trireme?

  • To embed Node.js apps inside an existing Java application
  • To run Node.js apps that take advantage of Java libraries you can't live without, like JDBC drivers and XML parsers

If neither of those reasons apply to you, then stick with "regular node!"

How do I get it?

From NPM

sudo npm install -g trireme
trireme -h
trireme <your script name here>

The NPM package for Trireme lets you run it on the command line just like "node".

Unfortunately, Trireme does not support the "repl" yet (and it's hard since Java gives us limited control over the TTY) so just running "trireme" with no arguments produces an error right now.

From Maven Central

The best reason to use Trireme is because it's important to embed Node.js code inside an existing Java application. In that case you will use the modules under "io.apigee.trireme" on Maven Central:

io.apigee.trireme

The "module map" later in this document shows which modules to use in which cases.

From GitHub

See the releases page to download the latest release files.

"trireme-x.y.z.jar" is always a stand-alone jar that you can run just like "node":

java -jar trireme-x.y.z.jar script.js

What version of Node.js does Trireme Support?

Trireme supports two versions of Node.js:

  • 0.10.32. This is the default, fully-supported version.
  • 0.12.7. This version is still a work in progress.

Support for Node.js 4.0 depends on more complete ES6 code in Rhino. The Rhino community is making progress on this but it will be quite some time before we are ready to support 4.0.

Running Trireme

Using NPM

If you installed Trireme using NPM, just run:

trireme <script name>

Trireme will execute your script just like Node.

In addition, the environment variable TRIREME_CLASSPATH may be used to add extra JARs or directories to the classpath used to run Trireme. Anything on this path will be appended to the classpath used to launch Trireme. This allows you to add JDBC drivers, etc.

For help, use:

trireme -h

Using Java

The "jar" module builds a self-contained JAR that may be used to launch Trireme on the command line just like regular Node.js:

mvn install
java -jar jar/target/trireme.X.Y.Z.jar <script name>

(and with no arguments it will launch the "repl" but that implementation is not complete)

For Apigee Edge Customers

Node.js apps on Apigee Edge run inside Trireme using a few specific settings that make them slightly different from the standard Trireme runtime. In particular, an "HTTP adaptor" is used, which is not 100% the same as the standard HTTP module. This does not affect most applications, but it may affect applications that depend on undocumented or internal functions and properties of the default HTTP module. (While this is a poor programming practice, it's quite common.)

In order to test applications that will run on Apigee Edge in the most compatible environment, the module "samples/apigee-edge-like-runner" will build a self-contained JAR that sets up Trireme this way. Use it just like the "Using Java" link above:

mvn install
java -jar samples/apigee-edge-like-runner/target/apigee-edge-like-launcher-X-Y-Z-SNAPSHOT.jar <script name>

Embedding Trireme as a servlet

The war sample is a sample that shows how to assemble a Node.js application into a WAR file. It uses the trireme-servlet module to link the servlet to the Node.js script. Any script that operates as an HTTP server using the "http" module can be embedded in this way.

Embedding Trireme Anywhere Else that Java Runs

There is JavaDoc for the "NodeEnvironment" and "NodeScript" classes, and many other features. Here are the basics:

import io.apigee.trireme.core.NodeEnvironment;
import io.apigee.trireme.core.NodeScript;

// The NodeEnvironment controls the environment for many scripts
NodeEnvironment env = new NodeEnvironment();

// Pass in the script file name, a File pointing to the actual script, and an Object[] containg "argv"
NodeScript script = env.createScript("my-test-script.js",
                                     new File("my-test-script.js"), null);

// Wait for the script to complete
ScriptStatus status = script.execute().get();

// Check the exit code
System.exit(status.getExitCode());

Selecting the Node version

The all-in-one JAR, and the "trireme" NPM package, include code for both Node.js 0.10 and 0.12. To select a version from the command-line, use the "--node-version" option, like this:

trireme --node-version=0.12 foo.js

When embedding Trireme, select the version using the "setNodeVersion" method in the NodeScript class.

With this scheme, both versions of Node can run inside the same JVM.

The version numbers are "semver-style" although they do not support every single feature of semver. The best bet is to use "0.10" and "0.12" to select each.

Trireme Extensions

There are a few NPM modules that only work in Trireme. These allow access to features of the Java platform that are normally accessed via native code in regular Node.js. These modules are as follows:

  • trireme-jdbc: This module provides access to JDBC drivers from inside Node.js code. This makes it possible to use databases that have excellent JDBC drivers (such as Oracle) without compiling any native code.
  • trireme-xslt: This module provides access to the XSLT processor inside the Java platform, which is faster and can support more of the XSLT standard than any of the native Node.js options.
  • trireme-support: Additional Trireme-specific support functions. These include the ability to detect if Trireme is being used, and the ability to dyamically load additional Node.js modules from a JAR file.

Logging

Trireme uses slf4j for logging the stuff that is happening in Java. The pre-built JAR, and the NPM "trireme" wrapper, use "slf4j-simple". To turn on debug logging, set the system property "org.slf4j.simpleLogger.defaultLogLevel" to "debug". (Or "trace" for even more output.)

When embedding trireme, you can use any SLF4J-compatible logging framework you wish, such as logback.

How Complete is Trireme?

Trireme supports most of the Node.js APIs and passes much of the Node.js test suite.

The table below shows each module and its status. "Complete" means that a module is functionally complete, although it may not necessarily pass all the node.js tests.

<table> <tr><td><b>Module</b></td><td><b>Status</b></td><td><b>Source</b></td></tr> <tr><td>assert</td><td>Complete</td><td>node.js</td></tr> <tr><td>child_process</td><td>Partial</td><td>Trireme</td></tr> <tr><td>cluster</td><td>Not Implemented Yet</td><td>node.js</td></tr> <tr><td>console</td><td>Complete</td><td>node.js</td></tr> <tr><td>crypto</td><td>Complete</td><td>node.js + Trireme</td></tr> <tr><td>debugger</td><td>Not Supported</td><td><NA/td></tr> <tr><td>dgram</td><td>Complete</td><td>node.js + Trireme</td></tr> <tr><td>dns</td><td>Complete</td><td>Trireme</td></tr> <tr><td>domain</td><td>Complete</td><td>node.js + Trireme</td></tr> <tr><td>events</td><td>Complete</td><td>node.js</td></tr> <tr><td>fs</td><td>Complete</td><td>node.js + Trireme</td></tr> <tr><td>globals</td><td>Complete</td><td>node.js + Trireme</td></tr> <tr><td>http</td><td>Complete</td><td>node.js + Trireme</td></tr> <tr><td>https</td><td>Complete but See Notes</td><td>Trireme</td></tr> <tr><td>module</td><td>Complete</td><td>node.js</td></tr> <tr><td>net</td><td>Complete</td><td>node.js + Trireme</td></tr> <tr><td>os</td><td>Partial</td><td>Trireme</td></tr> <tr><td>path</td><td>Complete</td><td>node.js</td></tr> <tr><td>process</td><td>Complete</td><td>Trireme</td></tr> <tr><td>punycode</td><td>Complete</td><td>node.js</td></tr> <tr><td>querystring</td><td>Complete</td><td>node.js</td></tr> <tr><td>readline</td><td>Partial</td><td>node.js</td></tr> <tr><td>repl</td><td>Not Supported</td><td>node.js</td></tr> <tr><td>stream</td><td>Complete</td><td>node.js</td></tr> <tr><td>string_decoder</td><td>Complete</td><td>node.js</td></tr> <tr><td>timers</td><td>Complete</td><td>node.js + Trireme</td></tr> <tr><td>tls</td><td>Complete but See Notes</td><td>Trireme</td></tr> <tr><td>tty</td><td>Complete</td><td>Trireme</td
View on GitHub
GitHub Stars484
CategoryDevelopment
Updated3mo ago
Forks51

Languages

JavaScript

Security Score

77/100

Audited on Dec 23, 2025

No findings