转自:https://opensource.com/article/18/4/benefits-javascript-vertx

If you are a Java programmer, chances are that you've either used JavaScript in the past or will in the near future. Not only is it one of the most popular (and useful) programming languages, understanding some of JavaScript's features could help you build the next uber-popular web application.

JavaScript on the server

The idea to run JavaScript on the server is not new; in fact, in December 1995, soon after releasing JavaScript for browsers, Netscape introduced an implementation of the language for server-side scripting with Netscape Enterprise Server. Microsoft also adopted it on Internet Information Server as JScript, a reverse-engineered implementation of Netscape's JavaScript.

The seed was planted, but the real boom happened in 2009 when Ryan Dahl introduced Node.js. Node's success was not based on the language but on the runtime itself. It introduced a single process event loop that followed the reactive programming principles and could scale like other platforms couldn't.

The enterprise and the JVM

Many enterprises have standardized on the Java virtual machine (JVM) as the platform of choice to run their mission-critical business applications, and large investments have been made on the JVM, so it makes sense for those organizations to look for a JVM-based JavaScript runtime.

Eclipse Vert.x is a polyglot-reactive runtime that runs on the JVM. Using Eclipse Vert.x with JavaScript is not much different from what you would expect from Node.js. There are limitations, such as that the JVM JavaScript engine is not fully compatible with the ES6 standard and not all Node.js package manager (npm) modules can be used with it. But it can still do interesting things.

Why Eclipse Vert.x?

Having a large investment in the JVM and not wanting to switch to a different runtime might be reason enough for an enterprise to be interested in Eclipse Vert.x. But other benefits are that it can interact with any existing Java application and offers one of the best performances possible on the JVM.

To demonstrate, let's look at how Vert.x works with an existing business rules management system. Imagine for a moment that our fictional enterprise has a mission-critical application running inside JBoss Drools. We now need to create a new web application that can interact with this legacy app.

For the sake of simplicity, let's say our existing rules are a simple Hello World:

package drools

//list any import classes here.

//declare any global variables here

rule "Greetings"
    when
        greetingsReferenceObject: Greeting( message == "Hello World!" )
    then
        greetingsReferenceObject.greet();
    end

When this engine runs, we get "Drools Hello World!" This is not amazing, but let's imagine this was a really complex process.

Implementing the Eclipse Vert.x JavaScript project

Like with any other JavaScript project, we'll use the standard npm commands to bootstrap a project. Here's how to bootstrap the project drools-integration and prepare it to use Vert.x:

# create an empty project directory
mkdir drools-integration
cd drools-integration

# create the initial package.json
npm init -y

# add a couple of dependencies
npm add vertx-scripts --save-dev
# You should see a tip like:
#Please add the following scripts to your 'package.json':
# "scripts": {
#   "postinstall": "vertx-scripts init",
#   "test": "vertx-scripts launcher test -t",
#   "start": "vertx-scripts launcher run",
#   "package": "vertx-scripts package"
# }

# add
npm add @vertx/web --save-prod

We have initialized a bare-bones project so we can start writing the JavaScript code. We'll start by adding a simple HTTP server that exposes a simple API. Every time a request is made to the URL http://localhost:8080/greetings, we should see the existing Drools engine's execution result in the terminal.

Start by creating an index.js file. If you're using VisualStudio Code, it's wise to add the following two lines to the beginning of your file:

/// <reference types="@vertx/core/runtime" />
/// @ts-check

These lines will enable full support and check the code for syntax errors. They aren't required, but they sure help during the development phase.

Next, add the simple HTTP server. Running on the JVM is not exactly the same as running on Node, and many libraries will not be available. Think of the JVM as a headless browser, and in many cases, code that runs in a browser can run on the JVM. This does not mean we can't have a high-performance HTTP server; in fact, this is exactly what Vert.x does. Let's start writing our server:

import { Router } from '@vertx/web';

// route all request based on the request path
const app = Router.router(vertx);

app.get('/greetings').handler(function (ctx) {
    // will invoke our existing drools engine here...
});

vertx
// create a HTTP server
.createHttpServer()
// on each request pass it to our APP
.requestHandler(function (req) {
    app.accept(req);
})
// listen on port 8080
.listen(8080);

The code is not complicated and should be self-explanatory, so let's focus on the integration with existing JVM code and libraries in the form of a Drools rule. Since Drools is a Java-based tool, we should build our application with a java build tool. Fortunately, because, behind the scenes, vertx-scripts delegates the JVM bits to Apache Maven, our work is easy.

mkdir -p src/main/java/drools
mkdir -p src/main/resources/drools

Next, we add the file src/main/resources/drools/rules.drl with the following content:

package drools

//list any import classes here.

//declare any global variables here

rule "Greetings"
    when
        greetingsReferenceObject: Greeting( message == "Hello World!" )
    then
        greetingsReferenceObject.greet();
    end

Then we'll add the file src/main/java/drools/Greeting.java with the following content:

package drools;

public interface Greeting {

String getMessage();

void greet();
}

Finally, we'll add the helper utility class src/main/java/drools/DroolsHelper.java:

package drools;

import org.drools.compiler.compiler.*;
import org.drools.core.*;
import java.io.*;

public final class DroolsHelper {

/**
   * Simple factory to create a Drools WorkingMemory from the given `drl` file.
   */
  public static WorkingMemory load(String drl) throws IOException, DroolsParserException {
    PackageBuilder packageBuilder = new PackageBuilder();
    packageBuilder.addPackageFromDrl(new StringReader(drl));
    RuleBase ruleBase = RuleBaseFactory.newRuleBase();
    ruleBase.addPackage(packageBuilder.getPackage());
    return ruleBase.newStatefulSession();
  }

/**
   * Simple factory to create a Greeting objects.
   */
  public static Greeting createGreeting(String message, Runnable andThen) {
    return new Greeting() {
      @Override
      public String getMessage() {
        return message;
      }

@Override
      public void greet() {
        andThen.run();
      }
    };
  }
}

We cannot use the file directly; we need to have drools. To do this, we add a custom property to our package.json named mvnDependencies (following the usual pattern):

{
    "mvnDependencies": {
        "org.drools:drools-compiler": "6.0.1.Final"
    }
}

Of course, since we updated the project file, we should update npm:

npm install

We are now entering the final step of this project, where we mix Java and JavaScript. We had a placeholder before, so let's fill in the gaps. We first use the helper Java class to create an engine (you can now see the power of Vert.x, a truly polyglot runtime), then invoke our engine whenever an HTTP request arrives.

// get a reference from Java to the JavaScript runtime
const DroolsHelper = Java.type('drools.DroolsHelper');
// get a drools engine instance
const engine = DroolsHelper.load(vertx.fileSystem().readFileBlocking("drools/rules.drl"));

app.get('/greetings').handler(function (ctx) {
  // create a greetings message
  var greeting = DroolsHelper.createGreeting('Hello World!', function () {
    // when a match happens you should see this message
    console.log('Greetings from Drools!');
  });

// run the engine
  engine.insert(greeting);
  engine.fireAllRules();

// complete the HTTP response
  ctx.response().end();
});

Conclusion

As this simple example shows, Vert.x allows you to be truly polyglot. The reason to choose Vert.x is not because it's another JavaScript runtime, rather it's a runtime that allows you to reuse what you already have and quickly build new code using the tools and language that run the internet. We didn't touch on performance here (as it is a topic on its own), but I encourage you to look at independent benchmarks such as TechEmpower to explore that topic.

Bring JavaScript to your Java enterprise with Vert.x的更多相关文章

  1. JavaScript前端和Java后端的AES加密和解密

    在实际开发项目中,有些数据在前后端的传输过程中需要进行加密,那就需要保证前端和后端的加解密需要统一.这里给大家简单演示AES在JavaScript前端和Java后端是如何实现加密和解密的. 直接上代码 ...

  2. atitit.js javascript 调用c# java php后台语言api html5交互的原理与总结p97

    atitit.js javascript 调用c# java php后台语言api html5交互的原理与总结p97 1. 实现html5化界面的要解决的策略1 1.1. Js交互1 1.2. 动态参 ...

  3. 卧槽! JavaScript JVM运行Java!!

    由于任何计算机语言都具有巨大的灵活性,软件世界变得有点疯狂.一旦你已经吸收了用这种语言编写的编译器的想法,那么它会编译还有什么可以留下来的?但是......用JavaScript编写的Java虚拟机J ...

  4. Cordova插件中JavaScript代码与Java的交互细节介绍

    在Cordova官网中有这么一张架构图:大家看右下角蓝色的矩形框"Custom Plugin"--自定义插件.意思就是如果您用Cordova打包Mobile应用时,发现您的移动应用 ...

  5. 解决Javascript md5 和 Java md5 中文加密后不同问题

    Javascript md5 和 Java md5 带中文字符加密结果不一致,可以通过编码进行转化. javascript可以使用encodeURLComponent将中文先转化一次再进行MD5加密. ...

  6. Eclipse里的Java EE视图在哪里?MyEclipse里的Java EE视图在哪里?MyEclipse里的MyEclipse Java Enterprise视图在哪里?(图文详解)

    为什么要写这篇博客呢? 是因为,最近接触一个web项目. 然后呢,Eclipse里的Java EE视图的位置与MyEclipse里不太一样.为了自己梳理日后查找,也是为了新手少走弯路. Eclipse ...

  7. 敏捷自己主动化单元測试 (从前台 JavaScript 至后台 Java)

    此份材料的内容适用于前台 JavaScript 与后台 Java 的单元測试◦ 希望, 能协助开发者可在最短的时间内, 开展单元測试的工作◦ 附件: 敏捷自己主动化单元測试 例子代码: QUnit 例 ...

  8. JavaScript翻译成Java

    这两天公司有一个需求,将一段加密的JavaScript代码转换为JAVA版. JavaScript中的某一段代码: 前期查看了整个JavaScript代码,发现代码中,方法里面嵌套方法,各种不合规的变 ...

  9. Atititjs javascript异常处理机制java异常转换.js exception process

    Atititjs javascript异常处理机制java异常的转换.js exception process 1. javascript异常处理机制 Throw str Not throw erro ...

随机推荐

  1. springboot kafka 消费者

    <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://mave ...

  2. (十三)golang--程序流程控制

    1.顺序控制 若没有判断,没有跳转,程序由上至下依次执行 2.分支控制 单分支if 条件表达式 { 执行代码块} 双分支if 条件表达式 { 执行代码块1} else { 执行代码块2} 多分支if ...

  3. SQL Server ---------- 分离数据库 生成 .mdf文件

    1.首先查看你要分离的数据库存储的位置 选中需要分离的数据数据库右击鼠标点击属性 要是记不住建议    复制一下 2.分离数据库      生成  .mdf 文件 右击 -----> 任务 -- ...

  4. Prometheus 告警分配到指定接收组

    Prometheus 告警分配到指定接收组 route属性用来设置报警的分发策略,它是一个树状结构,按照深度优先从左向右的顺序进行匹配. 主要处理流程:1. 接收到Alert,根据labels判断属于 ...

  5. PHP小程序后端支付代码亲测可用

    小程序后端支付代码亲测可用 <?php namespace Home\Controller; use Think\Controller; class WechatpayController ex ...

  6. Linux 笔记 - 第二十四章 配置 Tomcat

    一.前言 Tomcat 是 Apache 软件基金会(Apache Software Foundation)Jakarta 项目中的核心项目,由 Apache.Sun 和其他一些公司及个人共同开发.使 ...

  7. DateTime的ToString方法格式

    新建一个.NET Core控制台项目,敲入如下代码: using System; namespace NetCoreDatetime { class Program { static void Mai ...

  8. 简单地判断判断两矩形相交/重叠 C#

    最近需要用到矩形相交算法的简单应用,所以特地拿一个很简单的算法出来供新手参考,为什么说是给新手的参考呢因为这个算法效率并不是很高,但是这个算法只有简简单单的三行.程序使用了两种方法来判断是否重叠/相交 ...

  9. BAT: Windows批处理更改当前工作路径

    最近项目上需要获取文件夹下所有文件信息,因为文件夹是在server上,所以想用批处理bat来获取该路径下所有文件信息,然后通过任务计划管理去每天自动运行bat去更新文件信息内容. 获取文件夹下所有文件 ...

  10. Gin-Go学习笔记七:Gin-Web框架 布局页面

    模板使用 页面布局 1>     一个html页面由:head部分,body部分,内部css,内部js,外联css,外联的js这几部分组成.因此,一个布局文件也就需要针对这些进行拆分. 2> ...