${post.fImageName}

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!

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.

Continue reading »

${post.fImageName}

PurpleJS - the alternative to Node.js for Java projects

Okey, so let's say that it's not really necessary to have an alternative to Node.js, but we all do like to have alternatives right? Many many many years ago, when I was only 2^5+8. I was thinking that it would be nice to combine the power of Java and my existing investments with the simplicity of JavaScript. JavaScript makes it easy to share code between client and server so it's only natural to run JavaScript on the server too. But I wanted at the same time the power of Java and what the JVM can provide. 

With Enonic XP, the combination of Java and JavaScript is used to  speed up the development process and allow frontend developers to implement backend services. I saw that this was a very popular approach to develop software more effectively, and wanted everyone to be able to use the technology for free and in existing investments. PurpleJS was born.

What is PurpleJS?

PurpleJS is an alternative to Node.js for Java projects. PurpleJS makes it easy to build performant and lightweight Javascript server applications without the complexity of Node.js asynchronous programming model.

PurpleJS gives Javascript developers access to the vast Java community and the robustness and performance of the JVM. Java developers benefit from the simplicity and flexibility of Javascript in their projects.

Use PurpleJS when you want to:

  • code Javascript, but your application needs to run on the JVM
  • build fast and lightweight multithreaded applications with Javascript
  • create server applications with Javascript but access and use Java libraries
  • deliver isomorphic applications - running the same code on both client (i.e. browser) and server
  • build Javascript server applications that run on any infrastructure
  • code fast, no need to compile or re-deploy - especially useful for front-end projects
  • extend existing Java applications with Javascript
  • participate in the Javascript movement while leveraging your existing projects in Java

PurpleJS is a simple and capable framework for creating performant web applications without leaving Javascript. It is created in Java to give the flexibility and performance Java provides.

Getting started

I'll show you how to get started building your first web-application in PurpleJS.

You need to install two things: Java SDK and Gradle.  

Java is needed since PurpleJS is built on Java - that does not mean that you will ever need to program in Java, it's only the runtime. Gradle is a build system that is used for building applications in PurpleJS.

There are multiple ways to create a PurpleJS application, but the fastest is to use PurpleJS Boot. This is a ready-to-go server that's running Jetty and you do not need to worry about anything except your own application logic.

Setting up the project

To set up the project create a directory to hold the project files - like myapp. Go into the directory and create a file called build.gradle. This file should contain the following:

https://gist.github.com/srs/83f96a5f43ecddc4fe045d225e767a77

To test if this works, start the server by issuing the following command:

https://gist.github.com/srs/f46323314bac41cc2004632a892d0fb7

If everything works, you will see something like this:

https://gist.github.com/srs/b24435ae745d02dda1d36066020414ea

Congratulations, the project is now set up and we can start coding our application. Let's leave the application running. The system will pick up any changes so we do not need to restart the server while coding.

Main application file

If we open our browser and go to http://localhost:8080 we will see an error saying that /app/main.js is not found. This is our main entry-point for the application and it is required.

So, let's create the file src/main/resources/app/main.js and add the following:

https://gist.github.com/srs/f661826d56aa76aa2de93ceef0d05f3f

When we now refresh our browser again (http://localhost:8080), then a Hello World message appears. Simple, but this illustrates how simple it is to create a controller. You export the HTTP method that should be handled and returns the response. This response has properties like body,  contentType,  headers and status. The status is default set to 200 (OK). If we want to return JSON instead, just set a JSON-array or JSON-object to the body property.

https://gist.github.com/srs/142379437558081ac3638dd4b38015d1

The above example will output { name: 'Bill', age: 60 } with status = 200 and contentType = 'application/json'.

Request parameters

Request can contain various information. If you need to see what’s inside the request, just return the entire object as JSON like this:

https://gist.github.com/srs/91a78ad4281ad0a632e1f3a35635fa78

Let's modify main.js to implement a random generator that returns a random number between 1 and max. The max parameter should be read from max request parameter. First, we define the random number function.

https://gist.github.com/srs/8d00d03b89cdb91fa687c0b27b6e1bbc

Then we modify our exports.get function to return the random number based on a request parameter.

https://gist.github.com/srs/fdca444f4f1df0712aab79a84ab3a6e4

If we now access http://localhost:8080 without any parameters, we will get a random number between 1 and 10. Requesting http://localhost:8080?max=100 will give a random number between 1 and 100.

Routing

Sooner or later you will find yourself in need of a router. A router can route requests to different controllers and you can split your logic up into multiple files. Let's change our main.js file to include a router.

https://gist.github.com/srs/5bb43c5239c8d3a15bed3f2f97c949ae

This router can be configured by adding one or more routes. Every route can match both HTTP method and path. Let's add a route to get a random number.

https://gist.github.com/srs/05d22636e57d5d75f14735046213986a

To make this work we will need to modify our exports.get method so it delegates to the router that we have just configured.

https://gist.github.com/srs/41b99ae1a21e3b20715496c36c8299ed

If we now request http://localhost:8080 we will get a 404 since we no longer have a route on /, but on /random. Accessing http://localhost:8080/random will now give us a random number between 1 and 10.

We can also use path parameters to configure a route. If we want to access a random number between 1 and 100 using the /random/100 we can add a route like this:

https://gist.github.com/srs/3d2b968f5352c28ba2cdc50a242f83b8

If you now access http://localhost:8080/random/100 it will give you a random number between 1 and 100.

What's next?

This post is just scratching the surface of what PurpleJS can do. Want to check out what more PurpleJS can do? Please checkout the following resources:

 

 

PurpleJS is a Javascript application framework running on the Java Virtual Machine. In this post I will tell you what PurpleJS is, why it was created and how to get started.

Continue reading »