Graal.js Archetype

Archetype to start mixed Java/JavaScript development on top of GraalVM - a JVM with polyglot capabilities. The GraalVM comes with a 100% compatible node.js implementation that can easily execute Java code as well as code in other scripting languages like Ruby, R language or Python.

License

License

UPL
Categories

Categories

JavaScript Languages Graal
GroupId

GroupId

com.oracle.graal-js
ArtifactId

ArtifactId

nodejs-archetype
Last Version

Last Version

0.3
Release Date

Release Date

Type

Type

jar
Description

Description

Graal.js Archetype
Archetype to start mixed Java/JavaScript development on top of GraalVM - a JVM with polyglot capabilities. The GraalVM comes with a 100% compatible node.js implementation that can easily execute Java code as well as code in other scripting languages like Ruby, R language or Python.
Project URL

Project URL

https://github.com/graalvm/graal-js-archetype
Project Organization

Project Organization

Oracle
Source Code Management

Source Code Management

https://github.com/graalvm/graal-js-archetype/tree/master

Download nodejs-archetype

How to add to project

<!-- https://jarcasting.com/artifacts/com.oracle.graal-js/nodejs-archetype/ -->
<dependency>
    <groupId>com.oracle.graal-js</groupId>
    <artifactId>nodejs-archetype</artifactId>
    <version>0.3</version>
</dependency>
// https://jarcasting.com/artifacts/com.oracle.graal-js/nodejs-archetype/
implementation 'com.oracle.graal-js:nodejs-archetype:0.3'
// https://jarcasting.com/artifacts/com.oracle.graal-js/nodejs-archetype/
implementation ("com.oracle.graal-js:nodejs-archetype:0.3")
'com.oracle.graal-js:nodejs-archetype:jar:0.3'
<dependency org="com.oracle.graal-js" name="nodejs-archetype" rev="0.3">
  <artifact name="nodejs-archetype" type="jar" />
</dependency>
@Grapes(
@Grab(group='com.oracle.graal-js', module='nodejs-archetype', version='0.3')
)
libraryDependencies += "com.oracle.graal-js" % "nodejs-archetype" % "0.3"
[com.oracle.graal-js/nodejs-archetype "0.3"]

Dependencies

test (2)

Group / Artifact Type Version
junit : junit jar 4.12
org.apache.maven.shared : maven-verifier jar 1.6

Project Modules

There are no modules declared in this project.

Node.js+Java Maven Archetype

Java developers are used to their fixed set of tools and working styles. Often Maven is used as a build tool in the server side enterprise development. JUnit as a testing harness and various Maven aware IDEs as a user interface to access these tools. Changing this workflow is hard, often impossible and contributes to the rigid stability of many enterprise level projects.

While GraalVM comes with a compeling polyglot story and offers language independent access to various industry standard frameworks (like node.js project) and smooth integration of these languages in/with Java, it provides no best advices or 'getting started' guidelines. It is up to individual users of GraalVM to figure everything out by themselves. Given the obstacles of multi language interop and the fact that it is unique (e.g. not documented on StackOverflow), it is hard or even close to impossible to get started.

The Node.js+Java Maven Archetype is here to change that. It gives you an easy way to create a working Maven project with selected examples that can be edited, compiled, debugged and unit tested in the context of GraalVM's node.js environment.

Getting Started

The Node.js+Java Maven Archetype releases are uploaded to Maven central repository. Thus, creation of your sample project is a matter of a few shell commands.

Change directory into an empty folder and invoke (here is an example of a command line interaction for Maven newbies):

$ mvn -DarchetypeGroupId=com.oracle.graal-js \
      -DarchetypeArtifactId=nodejs-archetype \
      -DarchetypeVersion=0.2 \
      archetype:generate \
      -DgraalvmPath=/graalvm-19.0.2/
# and optionaly any of these
      -DalgorithmJava=true \
      -DalgorithmJS=true \
      -DalgorithmRuby=true \
      -DalgorithmR=true \
      -DunitTest=true

after answering few questions about the name (e.g. artifactId), groupId (something like root package in Java) and version (usually 1.0-SNAPSHOT, to accept the default just press enter) of your project, the skeleton of it gets generated. Change path to its root directory:

$ cd yourArtifactId

Now it is possible to compile and unit test it and also execute:

$ mvn package exec:exec -DskipTests

The server gets started on port 8080 and you can access it in a browser or from a command line. By default it just returns the received URL, but (depending on the selected samples) it also demonstrates how to compute factorial in polyglot languages:

$ curl http://localhost:8080/test
Received: /test
$ curl http://localhost:8080/java/30
265252859812191058636308480000000
$ curl http://localhost:8080/js/10
3628800

In case you enabled Ruby or R language you can also try:

$ curl http://localhost:8080/ruby/100
Received: /ruby/100
$ curl http://localhost:8080/r/5
Received: /r/5

The node.js runtime spiced with a polyglot flavor is now accessible via your standard Java development tooling.

The Benefits of Polyglot

The generated samples are simple, yet powerful enough to demonstrate the benefits of polyglot runtime like GraalVM over standard, single language runtimes.

Using Better Arithmetic

Different languages offer different types of numbers. For some computations using arithmetic from a different language may be beneficial. Just compare:

$ curl http://localhost:8080/js/50
3.0414093201713376E64
$ curl http://localhost:8080/r/50
3.041409320171302E64
$ curl http://localhost:8080/ruby/50
30414093201713378043612608166064768844377641568960512000000000000
$ curl http://localhost:8080/java/50
30414093201713378043612608166064768844377641568960512000000000000

while JavaScript and R languages use double precision numbers and round the result of 50! for bigger numbers. Both Ruby and Java offer built-in type numbers (fixnum and BigInteger respectively) that can handle numbers with arbitrary precision.

Better Libraries

Some languages offer better libraries for certain tasks than others. Take a look at R language implementation of factorial - it calls just a single function (called factorial obviously). Of course, it is not hard to write factorial in any language, but for certian type of tasks there are more suitable libraries in different languages than one is using primarily. GraalVM let's you merge them at full speed.

Multithreadedness of Java

The Java factorial example shows another benefit of using GraalVM - Java is inherently multi-threaded system. As such it is possible to execute compilation outside of main node.js event loop leaving it free for other computations. Try some long running computation in background followed by a simple query sent later:

$ curl http://localhost:8080/java/90000 &
$ curl http://localhost:8080/js/5
120.0
# later the huge result for 90000! is printed

Java gives us an easy to use paralelism that would be hard to achieve in a single threaded language like JavaScript and environments like node.js.

Contributing

Improvements to the archetype to better show the greatness of synergy between Java Virtual Machine and node.js are welcomed. Contribute to this project by forking its repository.

First step is to compile and register the development version 1.0-SNAPSHOT of Node.js+Java Maven Archetype into your local Maven repository. To do so invoke:

graal-js-archetype$ mvn -f archetype/ clean install -DskipTests

Once done, you can start creating your projects. You can use the same steps as with released versions, just specify 1.0-SNAPSHOT as the archetypeVersion:

$ mvn -DarchetypeCatalog=local \
      -DarchetypeGroupId=com.oracle.graal-js \
      -DarchetypeArtifactId=nodejs-archetype \
      -DarchetypeVersion=1.0-SNAPSHOT \
      archetype:generate \
      -DgraalvmPath=/graalvm-19.0.2/

Make your modifications in archetype/src/main/resources/ directory. It contains the template files which are then processed by velocity templating engine into final form when instantiating the archetype:

graal-js-archetype$ find archetype/src/main/resources/
archetype/src/main/resources/archetype-resources/nbactions.xml
archetype/src/main/resources/archetype-resources/pom.xml
archetype/src/main/resources/archetype-resources/src/main/java/Services.java
archetype/src/main/resources/archetype-resources/src/main/js/launcher.js
archetype/src/main/resources/archetype-resources/src/main/js/package.json
archetype/src/main/resources/archetype-resources/src/test/java/ServicesTest.java
archetype/src/main/resources/META-INF/maven/archetype-metadata.xml

once your modifications are done, repeat the development steps. Install the archetype into your local repository, use it and so on, so on.

When you are happy with your changes, invoke the tests that verify the archetype works in all known configurations:

graal-js-archetype/archetype$ mvn clean install

The tests take a while, yet ensures quality of your contribution.

UI for the Archetype

Using the Maven Archetype from a command line requires an expert knowledge. It is way more comfortable to do so from a GUI. There are extensions to NetBeans to simplify the configuration and debugging:

Java+node.js in NetBeans

com.oracle.graal-js

GraalVM

Universal VM for a polyglot world. Our mission: Make development more productive and run programs faster anywhere.

Versions

Version
0.3
0.2
0.1