Bring JavaScript to your Java enterprise with Vert.x
转自: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:
//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:
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:
/// @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:
// 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/resources/drools
Next, we add the file src/main/resources/drools/rules.drl with the following content:
//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:
Finally, we'll add the helper utility class src/main/java/drools/DroolsHelper.java:
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:
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.
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的更多相关文章
- JavaScript前端和Java后端的AES加密和解密
在实际开发项目中,有些数据在前后端的传输过程中需要进行加密,那就需要保证前端和后端的加解密需要统一.这里给大家简单演示AES在JavaScript前端和Java后端是如何实现加密和解密的. 直接上代码 ...
- 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. 动态参 ...
- 卧槽! JavaScript JVM运行Java!!
由于任何计算机语言都具有巨大的灵活性,软件世界变得有点疯狂.一旦你已经吸收了用这种语言编写的编译器的想法,那么它会编译还有什么可以留下来的?但是......用JavaScript编写的Java虚拟机J ...
- Cordova插件中JavaScript代码与Java的交互细节介绍
在Cordova官网中有这么一张架构图:大家看右下角蓝色的矩形框"Custom Plugin"--自定义插件.意思就是如果您用Cordova打包Mobile应用时,发现您的移动应用 ...
- 解决Javascript md5 和 Java md5 中文加密后不同问题
Javascript md5 和 Java md5 带中文字符加密结果不一致,可以通过编码进行转化. javascript可以使用encodeURLComponent将中文先转化一次再进行MD5加密. ...
- Eclipse里的Java EE视图在哪里?MyEclipse里的Java EE视图在哪里?MyEclipse里的MyEclipse Java Enterprise视图在哪里?(图文详解)
为什么要写这篇博客呢? 是因为,最近接触一个web项目. 然后呢,Eclipse里的Java EE视图的位置与MyEclipse里不太一样.为了自己梳理日后查找,也是为了新手少走弯路. Eclipse ...
- 敏捷自己主动化单元測试 (从前台 JavaScript 至后台 Java)
此份材料的内容适用于前台 JavaScript 与后台 Java 的单元測试◦ 希望, 能协助开发者可在最短的时间内, 开展单元測试的工作◦ 附件: 敏捷自己主动化单元測试 例子代码: QUnit 例 ...
- JavaScript翻译成Java
这两天公司有一个需求,将一段加密的JavaScript代码转换为JAVA版. JavaScript中的某一段代码: 前期查看了整个JavaScript代码,发现代码中,方法里面嵌套方法,各种不合规的变 ...
- Atititjs javascript异常处理机制java异常转换.js exception process
Atititjs javascript异常处理机制java异常的转换.js exception process 1. javascript异常处理机制 Throw str Not throw erro ...
随机推荐
- 是的 你没看错!!!用JAVA为MCU开发物联网程序?
是的 你没看错!!!用JAVA为MCU开发物联网程序? 一直以来,物联网设备这种嵌入式硬件,对于Java软件开发者来说,就是Black Magic Box,什么中断.寄存器,什么 ...
- mvn手动上传jar到本地仓库
mvn install:install-file -Dfile=G:\elastic-project\workspace\out\artifacts\xxl_job_core_jar\xxl-job- ...
- 安装Office 2016 出现 Office 16 Click-to-Run Extensibility Component
无法安装 64 位版本的 Office,因为在您的 PC 上找到了以下 32 位程序: Office 16 Click-to-Run Extensibility Component 请卸载所有 32 ...
- ABA问题的产生及解决
什么是ABA问题 在CAS算法中,需要取出内存中某时刻的数据(由用户完成),在下一时刻比较并交换(CPU保证原子操作),这个时间差会导致数据的变化. 1.线程1从内存位置V中取出A2.线程2从内存位置 ...
- redis启动出现错误 can't chdir ...
启动redis出现以下错误:[15816] *********** # Can't chdir to ’**********‘ :No such file or directory 解决方法:手动创建 ...
- Redis(三)数据类型
之前的文章中说了Redis的常见应用场景和特性,在特性章节中也大致说了数据结构契合场景.因为我想在更深入.更全面的学习Redis之前,了解场景和特性,才能在学习时更加全面且理解更透彻: redis的什 ...
- Java中转换为十六进制的几种实现
public class HexUtil { private static final String[] DIGITS_UPPER = {"0", "1", & ...
- java8时间处理实例
实例: package com.javaBase.time; import java.time.Clock; import java.time.LocalDate; import java.time. ...
- Python中的@函数装饰器到底是什么?
在解释@函数装饰器之前,先说一下,类中的类方法和静态方法. 在Python中完全支持定义类方法.静态方法.这两种方法很相似,Python它们都使用类来调用(ps:用对象调用也可以). 区别在于:Pyt ...
- mac下搭建Apache服务器环境
mac下自带了一个Apache服务环境,所以不需要另外去下载,直接配置就好了. 一.启动Apache服务 在终端下输入 sudo apachectl start , 启动Apache服务.在浏览器输入 ...