NodeJS is the best known and most popular way of executing JavaScript on the server. If you have existing investments in Java and see the benefits of using the Java VM, then NodeJS might not be an ideal approach. Luckily, the JVM provides Javascript support and with it many alternatives to NodeJS.
5 alternatives to NodeJS for Java
Having developed software for more than 3 decades, I have used most of the popular languages out there. I was forced into coding Javascript since it's running on virtually all browsers out there. It's a very popular language nowadays and ranks pretty high on the TIOBE popularity index.
Executing JavaScript on the server is a natural thing to do, because you can then concentrate on learning one language. You can even refactor out common code that will execute both on the client and the server - this is called isomorphic code.
NodeJS is the best known and most popular engine for executing JavaScript on the server, but there are actually many ways to do this. Here are some projects worth checking out.
DIY
Lets start off hardcore, with the "Do It Yourself" approach. Developers love to create frameworks, so why should this be different? To create an alternative to NodeJS on the JVM, first you need a Javascript runtime. You definetly do not want to build the Javascript runtime from scratch. There are many Javascript-runtimes available for the JVM. The main ones are Rhino and Nashorn - both big and reasonable fast animals. Rhino is bundled with Java 7 and earlier, while Nashorn is bundled with Java 8 and later. Nashorn is the successor of Rhino and is much faster since it's using a lot of new optimization techniques.
The next thing you will need, is some sort of module system. CommonJS defines a module system, which is what NodeJS uses. It's wise to focus on that since it's basically the standard. There are several CommonJS implementations for Rhino that works pretty well. If you are using Nashorn, you will need to build this yourself since all the other implementations out there are either faulty or simply too slow.
Next, you will probably need an http-bridge and some sort of pluggability. Then, unless you are fully NodeJS compliant, you will have to add reusable modules to make it work for your own and other's projects.
Trust me when I say, a DIY solution is a lot of work if you need something more than just running plain Javascript on the server. I have first hand experience building a NodeJS alternative in Java which you can read about later in this article. You might be better off choosing one of the existing ones below.
Vert.x
Eclipse Vert.x is a toolkit for building reactive web applications on the Java platform. It's very pluggable and speaks multiple languages - aka polyglot. That means you may freely choose your language, and JavaScript might be one of your choices. In Vert.x you have full control over the server runtime. If you are developing a web application, you actually need to create the http server in your code.
Everything in Vert.x is reactive. That means it is non-blocking by nature, like NodeJS. This programming technique can be difficult for Java programmers, at least to switch to thinking in a reactive way. Some features are not implemented in a straight forward way in the code, so the code tends to be hard to read unless you are not used to it.
The main purpose of being reactive and non-blocking is speed. Vert.x is fast, but the speed varies between programming languages. Vert.x uses the new Nashorn for its JavaScript engine.
Vert.x is very pluggable and has a lot of existing modules. It's nicely separated into a core, language extensions and other extensions. This means that even the language support is pluggable, which is very cool indeed.
One of the problems with Vert.x, as I see it, is that you pretty much need to implement your entire application on it. I know you can mix and match, but I found it hard to make it play nicely with my existing application. For a micro-service architecture it probably does not matter since your "glue" is the network.
RingoJS
RingoJS has been out for a while. It was one of the first JavaScript alternatives to NodeJS I looked at. I was really inspired by this project as it has a lot of NodeJS functionality out of the box. RingoJS is multi-threaded and not reactive. It's built upon the old Rhino JavaScript engine and sadly not the newer Nashorn.
Since everything in RingoJS is multi-threaded it's much easier (in my opinion) to read the examples and start programming the way you are used to. It comes at a cost, but for low to medium scale web applications it should be just fine. Web services are implemented using JSGI (JavaScript Gateway Interface) which is a standard from the CommonJS people. Implementing web services in RingoJS is pretty simple and straight forward, very much like what Express does in NodeJS.
There are many out of the box libraries, and there is even a package manager for downloading and managing external packages. This package manager communicates with the package portal available on packages.ringojs.org. Since Ringo supports CommonJS modules (aka require), you can probably use several existing NodeJS modules as well, but I have not tried that. Integrating with existing Java libraries is also a breeze since it's built on Rhino. Rhino has extensible support for bridging Java and JavaScript and the other way around.
If you want to use RingoJS on your own server, they provide a servlet for doing that. This means that you can dispatch requests from your existing spring application or J2EE application to some JavaScript that handles the request.
I would really like to see it using Nashorn instead of the old Rhino. Also it seems a bit foreign for us Java developers. It feels like investing in a NodeJS replacement, instead of just an alternative.
Nodyn
Nodyn is a little different from the rest. It tries hard to implement full NodeJS compatibility - so it's actually a total replacement, not just an alternative approach. The JavaScript engine used is DynJS, which is much more performant than Rhino. Not sure how it stacks up with Nashorn since I have not seen any benchmarks on that.
You can use Nodyn in two ways, either as a NodeJS replacement writing everything in JavaScript or embedded into your own system. Both ways of doing it, gives you excellent support for your existing Java investments. If you are using it as a NodeJS replacement, then you will load your existing Java libraries using some of the Nodyn's API's.
The only problem I see, is the lack of servlet support. If you want to write your http web service logic in JavaScript while still working with J2EE servlets, then you are out of luck or you will need to build this yourself. Also not sure if you will ever need to replace NodeJS since it will probably never be a full blown 100% replacement anyway.
PurpleJS
PurpleJS is another alternative for NodeJS running on Java. It's one of the projects I have been working on, so I will try to be very objective when writing about it. As stated earlier there are a lot of inner workings that you have never considered when trying to create such a project. Luckily for me I had hands on experience building another framework inside a well known Web Platform, so I took all the knowledge that I had from that project, put it into PurpleJS - and improved it for the better.
PurpleJS uses Nashorn as the JavaScript engine. Since Nashorn does not implement CommonJS module support (aka require), PurpleJS implements that in it's own way. Instead of searching the file-path it searches inside JAR files - this is the default behaviour and can be overridden.
Implementation of JavaScript http services is pretty easy and follows the same pattern as JSGI (JavaScript Gateway Interface), even if it's not directly compatible. It also implements an express like router for request routing. It supports http websockets support out of the box, which makes it dead easy to use. Even if it's easy to create web applications with PurpleJS, it is not limited to that - command-line applications can also be implemented using the framework.
PurpleJS is designed for rapid application development, and one of the key features is that you seldom need to reload on changes. Code is instantly refreshed if the files are changed. Executing Java code inside your JavaScript is the same as for Nashorn, but the framework hides this by providing reusable modules via it's plugin framework. Embedding PurpleJS is also very easy to do, as it provides an integration API to build integrations on. Spring and J2EE support are not there yet, but will be in the future. The default approach to PurpleJS also uses plain Maven-style modules and Gradle for building.
For now, PurpleJS uses a multi-threaded model and the http-layer is not async or reactive in itself. This can be a limitation for some, but I find it easier to build and debug applications using a more straight-forward model.
What's Next?
Now you know some alternative approaches to NodeJS. There are more, but I did not have the time to review all of them. If you want to explore the possibility to use JavaScript on the server, there are at least 4 excellent alternatives described above. I trust you to wait with developing your DIY solution until absolutely needed - and I actually bet you won't need it - ever!