JSR223
Java中调用其他脚本语言可以通过JSR223来实现。JSR223规范定义了脚本调用的抽象,只要拥有对应脚本的JSR223的实现,即可实现Java对对应脚本的调用。
例如,下面是对JS脚本的调用
1 2 3 4 5 6 7 8
| import javax.script.*; public class HelloWorld { public static void main(String[] args) throws ScriptException { ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("JavaScript"); engine.eval("print ('Hello World')"); } }
|
Ruby的调用
JRuby提供了Ruby脚本的的JSR223的实现。只需直接依赖JRuby的包
1 2 3 4 5
| <dependency> <groupId>org.jruby</groupId> <artifactId>jruby</artifactId> <version>${jruby.version}</version> </dependency>
|
引擎名为jruby
1 2 3 4 5 6 7
| ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("jruby") Bindings bindings = new SimpleBindings() bindings.put("message", "global variable") String script = "puts $message" engine.eval(script, bindings);
|
使用gem
Jruby增强了RubyGems,它会寻找classpath下的specifications目录并自动地添加到Gem.path
目录下,这意味着可以把整个gem repository打包成jar文件。
首先,需要通过安装需要的gem的来创建gem repository
1 2 3 4 5 6
| $ java -jar jruby-complete-1.1.6.jar -S gem install -i ./chronic-gems chronic --no-rdoc --no-ri Successfully installed rubyforge-1.0.2 Successfully installed rake-0.8.3 Successfully installed hoe-1.8.2 Successfully installed chronic-0.2.3 4 gems installed
|
然后打成jar包,注意jar包的名称不要和gem的名称一样(例如chronic.jar),否则当你require 'chronic'
的时候JRuby会加载chronic.jar
1
| $ jar cf chronic-gems.jar -C chronic-gems .
|
然后可以查看jar包中所包含的gem
1
| java -jar jruby-complete-1.1.6.jar -S gem list
|
NodeJS的调用
J2V8是V8引擎的Java Binding,它通过JNI调用来实现NodeJS的调用。下面是一个调用NPM模块的例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public static void main(String[] args) { final NodeJS nodeJS = NodeJS.createNodeJS(); final V8Object jimp = nodeJS.require(new File("path_to_jimp_module")); V8Function callback = new V8Function(nodeJS.getRuntime(), new JavaCallback() { public Object invoke(V8Object receiver, V8Array parameters) { final V8Object image = parameters.getObject(1); executeJSFunction(image, "posterize", 7); executeJSFunction(image, "greyscale"); executeJSFunction(image, "write", "path_to_output"); image.release(); return null; } }); executeJSFunction(jimp, "read", "path_to_image", callback); while(nodeJS.isRunning()) { nodeJS.handleMessage(); } callback.release(); jimp.release(); nodeJS.release(); }
|
Spring Integration
Spring Integration 2.1开始支持对JSR223实现的集成调用。 通过Service Activator即可实现方法调用
1 2 3 4 5 6 7 8 9 10 11 12 13
| <service-activator input-channel="input"> <script:script lang="ruby" variables="foo=FOO, date-ref=dateBean"> <script:variable name="bar" ref="barBean"/> <script:variable name="baz" value="bar"/> <![CDATA[ payload.foo = foo payload.date = date payload.bar = bar payload.baz = baz payload ]]> </script:script> </service-activator>
|
再配合Gateway,实现无缝的方法调用
1 2 3 4
| <gateway service-interface="com.some.Foo" default-request-channel="input" default-reply-timeout="10000" default-reply-channel="reply" />
|