文档章节

嵌入式Jruby

YuMG
 YuMG
发布于 2015/06/12 23:14
字数 3761
阅读 70
收藏 0
点赞 0
评论 0

0.嵌入式Jruby

能够在Ruby中使用Java是JRuby最广为人知的特性,那么,反过来在Java中使用Ruby也同样是允许的,你可以在Java中执行一个完整的Ruby脚本、或者单独调用其中的一个Ruby方法,甚至使用Ruby实现Java接口。想要做到这一点,可以通过多种不同的方式。我们把这些技术统称作为“嵌入式”技术。本文内容将介绍如何在Java工程中嵌入JRuby。

1.JRuby Embed ( 原称 Red Bridge )

Jruby一直以来就拥有一套 私有的 嵌入式API(原始API)。这套API与运行时内部紧密地耦合,在Jruby快速进化的过程中,这套API同时也频繁的发生变更。从1.4版本以后,Jruby提供了更加稳定的公共API,最初被称为 Reb bridge ,现如今称为 JRuby Embed。虽然,旧的原始私有API在遗留程序中可能还能继续工作,但是,对于新项目而言,强烈推荐使用新的公开API。不过,需要注意的是,使用 JRuby Embed 尽管可以完全胜任“ruby脚本执行”、“在Java与Ruby之间共享变量”之类的工作,但是如果存在更高级别的需求,比如在java里控制创建Jruby实例,那么就只能求助于最原始的API了。

1.1 Features of Red Bridge

Red Bridge 可以从以下两个层面进行使用:

  • 底层的Embed Core
  • 基于Embed Core提供的JSR223和BSF(Bean Scripting Framework)实现

Embed Core是Jruby特有的,可以充分发挥JRuby的各种能力。JSR223与BSF是针对各种不同脚本语言的通用接口。

上述API形式该如何选择呢?对于只是用到Ruby脚本的项目,推荐使用Embed Core。原因如下:

  1. 使用Embed Core你可以在一个JVM中创建多个Ruby环境,并且分别进行单独的配置。JSR223和BSF下,你只能通过System属性进行全局的设置。
  2. Embed Core提供了许多简化便捷操作,比如从java.io.InputStream中加载脚本,或者从Ruby代码中返回一个Java友好的对象。这些功能,使得你可以略过许多繁琐的模板式的设置。

而对于需要处理多种类型脚本语言的项目,JSR223会更合适。虽然它是中立于语言的,但是JRuby关于JSR223的实现允许你去设置一些Ruby特有的选项。尤其是,你可以控制脚本引擎的线程模型、本地变量的生命周期、编译模式以及行号的显示方式。

突出重点地说,Red Bridge的优势主要在于以下两点:

1.1.1 Context Type

上下文类型(单例[singleton]、线程安全[thread-safe]、单线程[single-threaded]、并发[concurrent])决定了JRuby如何维护它内部的Ruby状态。关于以上类型的错误选择,将会导致不可预知的严重错误。

简单的应用场景下你可能只需要一个Ruby runtime,而且你也不需要在多线程环境下来访问它,那么这时应该选用 singleton 类型。如果你要在多线程环境下运行Ruby脚本,你应该选择 thread-safe 类型。作为新引入的类型, concurrent 类型是一种混合了 singletonthread-safe的类型。在 concurrent 类型下,将会拥有一个Ruby runtime单例和多个本地的variable map。

1.1.2 Variables

“变量共享”是Red bridge提供的附加功能。借助于此,你可以为Ruby设置一些全局变量,然后再运行脚本之后,再通过全局变量来获取执行结果。

其实,通用的脚本API也可以通过 blunt instrument 来功效全局变量。不过,RedBridge提供了更强的功能,不仅限于共享全局变量,同样也可以共享本地变量与实例变量。JRuby使用了称为 variable map 的机制来追踪Java与Ruby之间的变量名值对。我们可以通过“变量选项”(various options)来控制variable map如何在不同的调用之间进行复用。

同样,你也可以通过方法参数传递数据,然后获取返回值。这些数据值在java端都是普通java对象。

自JRuby 1.4.0RC1版本以后,JRuby Embed (Red Bridge)的二进制版本被包含在JRuby的官方下载中。在1.5版本之后,Red Bridge源码被包含在JRuby core中。

JSR223与BSF是稳定的API。Embed Core API在某种程度上是稳定的,但在每个release版本之间不排除会有细小的变更。# JRuby Embed (originally known as Red Bridge)

2.Hello World 样例

不同形式API所依赖的JAR包。

  • Embed Core
    • jruby-complete.jar or jruby.jar
  • JSR223
    • ruby-complete.jar or jruby.jar
    • script-api.jar (if you are using JDK1.5)
  • BSF
    • jruby-complete.jar or jruby.jar
    • bsf.jar
    • commons-logging-[version].jar

2.1 Embed Core

package vanilla;

import org.jruby.embed.ScriptingContainer;

public class HelloWorld {

    private HelloWorld() {
        ScriptingContainer container = new ScriptingContainer();
        container.runScriptlet("puts 'Hello World!'");
    }

    public static void main(String[] args) {
        new HelloWorld();
    }
}

2.2 JSR223

package redbridge;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class Jsr223HelloWorld {

    private Jsr223HelloWorld() throws ScriptException {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("jruby");
        engine.eval("puts 'Hello World!'");
    }

    public static void main(String[] args) throws ScriptException {
        new Jsr223HelloWorld();
    }
}

2.3 BSF

package azuki;

import org.apache.bsf.BSFException;
import org.apache.bsf.BSFManager;

public class BsfHelloWorld {
    private BsfHelloWorld() throws BSFException {
        BSFManager.registerScriptingEngine("jruby", "org.jruby.embed.bsf.JRubyEngine", new String[] {"rb"});
        BSFManager manager = new BSFManager();
        manager.exec("jruby", "<script>", 0, 0, "puts 'Hello World!'");
    }

    public static void main(String[] args) throws BSFException {
        new BsfHelloWorld();
    }

}

3.配置

使用 JRuby Embed (RedBridge) 可以允许进行一些环境和执行方面的配置,大多数情况下默认的配置就是够用的。

使用Embed Core,各种配置主要是通过构造函数或者方法参数来设置;而对于JSR223,则主要是通过系统属性(System properties)来进行配置。

RedBridge支持对于每个“container”或者“evaluation”级别上的设置。当使用系统属性来进行“container”级别的配置时,必须在初始化“container”之前进行设置。当使用Embed Core提供的方法来进行设置时,那么必须在执行“container”的put/parse/runScriptlet方法之前进行设置,这些方法会基于container的设置来初始化Ruby runtime。一旦“Ruby runtime”初始化完毕,那么container的配置将不会再被引用。“evaluation”级别的配置应该在运行ruby代码之前进行设定。

  • Per-container configurations:
    • JRuby Home
    • Classpath
    • Context Instance Type
    • Local Variable Behavior
    • Compile Mode
    • Ruby Version
  • Per-evaluation configurations:
    • Disabling Sharing Variables
    • Line Number

3.1 JRuby Home

Scope: Per Container System Propety Name: jruby.home

JRuby Home 决定了JRuby到哪里去寻找内建库。JRuby Embed确定该路径的内部规则为:

  • 检查JRUBY_HOMEOS环境变量
  • 检查jruby.homeJVM系统属性
  • 检查ruby-complete.jar中的设置

使用OS环境变量或者JVM系统属性都将起到全局的效果。而使用Embed Core则可以对每个脚本容器实例进行不同的配置:

ScriptingContainer container = new ScriptingContainer();
// JRuby 1.5.x
container.setHomeDirectory("/Users/yoko/Tools/jruby-1.5.6");
// JRuby 1.4.0
//container.getProvider().getRubyInstanceConfig().setJRubyHome("/Users/yoko/Tools/jruby-1.3.1");

3.2 Class Path (Load Path)

Scope: Per Container System Propety Name: org.jruby.embed.class.path (or java.class.path)

当加载Ruby脚本或者Java Class时,将会用到Classpaths配置。Embed Core 和 BSF都有设置classpath的方法,而JSR223没有相关方法只能通过系统属性来进行设定。org.jruby.embed.class.path 或者 java.class.path都可以用来进行此项配置。以下是一些关于优先级顺序等发面的详细说明。

The org.jruby.embed.class.path system property is avaiable to use in Embed Core and BSF, too. In case of Embed Core and JSR223, a value assigned to org.jruby.embed.class.path is looked up first, then java.class.path. This means that only org.jruby.embed.class.path is used if exists. As for BSF, after java.class.path is looked up, org.jruby.embed.class.path is added to if exists. The format of the paths is the same as Java's class path syntax, :(colon) separated path string on Unix and OS X or ;(semi-colon) separated one on Windows. Be sure to set classpaths before you instantiate javax.script.ScriptEngineManager or register engine to org.apache.bsf.BSFManager.

另外还有一篇专门关于ClasspathAndLoadPath的主题。

Samples below run testMath.rb, which is included in JRuby’s source archive. The script, testMath.rb, needs minirunit.rb, which should be loaded from the classpath.

下方代码示例的场景为:运行testMath.rb,且该脚本中引用了minirunit.rb脚本。

为了能够在运行testMath.rb时正确地从classpath(loadpath)中加载minirunit.rb,不同的API代码样例如下。

3.2.1 Core

package vanilla;

import java.util.ArrayList;
import java.util.List;
import org.jruby.embed.PathType;
import org.jruby.embed.ScriptingContainer;

public class LoadPathSample {
    private final static String jrubyhome = "/Users/yoko/Tools/jruby-1.3.1";
    private final String filename = jrubyhome + "/test/testMath.rb";

    private LoadPathSample() {
        ScriptingContainer container = new ScriptingContainer();
        List<String> loadPaths = new ArrayList();
        loadPaths.add(jrubyhome);
        // JRuby 1.5.x
        container.setLoadPaths(loadPaths);
        // JRuby 1.4.0
        //container.getProvider().setLoadPaths(loadPaths);
        container.runScriptlet(PathType.ABSOLUTE, filename);
    }

    public static void main(String[] args) {
        new LoadPathSample();
    }
}

3.3.2 JSR223

package redbridge;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.Reader;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class Jsr223LoadPathSample {
    private final static String jrubyhome = "/Users/yoko/Tools/jruby-1.3.1";
    private final String filename = jrubyhome + "/test/testMath.rb";

    private Jsr223LoadPathSample() throws ScriptException, FileNotFoundException {
        System.setProperty("org.jruby.embed.class.path", jrubyhome);
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("jruby");
        Reader reader = new FileReader(filename);
        engine.eval(reader);
    }

    public static void main(String[] args) throws ScriptException, FileNotFoundException {
        new Jsr223LoadPathSample();
    }
}

3.3.3 BSF

package azuki;

import java.io.FileNotFoundException;
import org.apache.bsf.BSFException;
import org.apache.bsf.BSFManager;
import org.jruby.embed.PathType;

public class BsfLoadPathSample {
    private final static String jrubyhome = "/Users/yoko/Tools/jruby-1.3.1";
    private final String filename = jrubyhome + "/test/testMath.rb";
    
    private BsfLoadPathSample() throws BSFException, FileNotFoundException {
        BSFManager.registerScriptingEngine("jruby", "org.jruby.embed.bsf.JRubyEngine", new String[] {"rb"});
        BSFManager manager = new BSFManager();
        manager.setClassPath(jrubyhome);
        manager.exec("jruby", filename, 0, 0, PathType.ABSOLUTE);
    }

    public static void main(String[] args) throws BSFException, FileNotFoundException {
        new BsfLoadPathSample();
    }
}

3.4 Context Instance Type

Scope: Per Container Property Name: org.jruby.embed.localcontext.scope Value:

  • singleton(default in JRuby 1.6.x/1.5.x/1.4.0 and JRuby trunk; rev. 9e557a2 and later)
  • theadsafe (default in JRuby 1.4.0RC1, RC2, RC3)
  • singlethread
  • concurrent (since JRuby 1.6.0)

本地上下文中维护了以下内容:

  • Ruby runtime
  • Java与Ruby共享的“键值对”变量
  • 缺省 I/O streams (reader/writer/error writer)
  • 其它属性

3.4.1 Singleton

该模型应用了“单例模式”。无论创建了多少个ScriptingConatiners (or ScriptEngines (JSR223)),都只会有一个Ruby runtime和variable map,在该模式下线程安全由用户来负责。

+------------------------------------------------------------+
|                       Variable Map                         |
+------------------------------------------------------------+
+------------------------------------------------------------+
|                       Ruby runtime                         |
+------------------------------------------------------------+
+------------------+ +------------------+ +------------------+
|ScriptingContainer| |ScriptingContainer| |ScriptingContainer|
+------------------+ +------------------+ +------------------+
+------------------------------------------------------------+
|                         JVM                                |
+------------------------------------------------------------+

                Singleton Local Context Type
          (Thread safety is users' responsibility)

Core

ScriptingContainer instance = new ScriptingContainer(LocalContextScope.SINGLETON);

JSR223/BSF

System.setProperty("org.jruby.embed.localcontext.scope", "singleton");

3.4.2 ThreadSafe

在该模式下,脚本的parse(解析)和evaluation(执行)都可以在一个多线程的环境下安全执行。一个ScriptingContainer将会创建线程本地的Ruby runtimes 和 variable maps。

+------------------+ +------------------+ +------------------+
|   Variable Map   | |   Variable Map   | |   Variable Map   |
+------------------+ +------------------+ +------------------+
+------------------+ +------------------+ +------------------+
|   Ruby runtime   | |   Ruby runtime   | |   Ruby runtime   |
+------------------+ +------------------+ +------------------+
+------------------------------------------------------------+
|                     ScriptingContainer                     |
+------------------------------------------------------------+
+------------------+ +------------------+ +------------------+
|   Java Thread    | |   Java Thread    | |   Java Thread    |
+------------------+ +------------------+ +------------------+
+------------------------------------------------------------+
|                         JVM                                |
+------------------------------------------------------------+

                Threadsafe Local Context Type
       (Per Thread Isolated Variable Map and Runtime)

Core

ScriptingContainer instance = new ScriptingContainer(LocalContextScope.THREADSAFE);

JSR223/BSF

System.setProperty("org.jruby.embed.localcontext.scope", "threadsafe");

3.4.3 Concurrent

该模式中隔离了variable maps,但是共享了Ruby runtime。一个ScriptingContainer将会创建一个runtime和多个线程本地的variable maps。这种情况下全局变量和常量都不是线程安全的,但是跟java端绑定的变量或者常量都是线程本地的。

+------------------+ +------------------+ +------------------+
|   Variable Map   | |   Variable Map   | |   Variable Map   |
+------------------+ +------------------+ +------------------+
+------------------------------------------------------------+
|                        Ruby runtime                        |
+------------------------------------------------------------+
+------------------------------------------------------------+
|                     ScriptingContainer                     |
+------------------------------------------------------------+
+------------------+ +------------------+ +------------------+
|   Java Thread    | |   Java Thread    | |   Java Thread    |
+------------------+ +------------------+ +------------------+
+------------------------------------------------------------+
|                         JVM                                |
+------------------------------------------------------------+

                Concurrent Local Context Type
    (Per Thread Isolated Variable Map and Singleton Runtime)

Core

ScriptingContainer instance = new ScriptingContainer(LocalContextScope.CONCURRENT);

JSR223/BSF

System.setProperty("org.jruby.embed.localcontext.scope", "concurrent");

3.4.4 SingleThread

这个模型真的没什么用。

This model pretends as if there is only one thread in the world, and does not mind race condition at all. This naive model is used in many other JSR223 ScriptEngines. Users are responsible to thread safety.

+------------------+ +------------------+ +------------------+
|   Variable Map   | |   Variable Map   | |   Variable Map   |
+------------------+ +------------------+ +------------------+
+------------------+ +------------------+ +------------------+
|   Ruby runtime   | |   Ruby runtime   | |   Ruby runtime   |
+------------------+ +------------------+ +------------------+
+------------------+ +------------------+ +------------------+
|ScriptingContainer| |ScriptingContainer| |ScriptingContainer|
+------------------+ +------------------+ +------------------+
+------------------------------------------------------------+
|                         JVM                                |
+------------------------------------------------------------+

                Singlethread Local Context Type
          (Thread safety is users' responsibility)

Core

ScriptingContainer instance = new ScriptingContainer(LocalContextScope.SINGLETHREAD);

JSR223/BSF

System.setProperty("org.jruby.embed.localcontext.scope", "singlethread");

3.5 Local Variable Behavior Options

Scope: Per Container Property Name: org.jruby.embed.localvariable.behavior Value:

  • transient (default for core)
  • persistent
  • global (default for JSR223)
  • bsf (for BSF)

JRuby Embed 可以在java与ruby之间共享ruby的本地变量、实例变量、全局变量和常量。

3.5.1 Transient Local Variable Behavior

Embed Core的缺省设置。

  • 本地变量将在执行后被销毁,而不会再多次执行之间传递
  • 实例变量、全局变量和常量将会跟随ruby runtime共存。

以上基本遵从了ruby原本的语义。

Core

ScriptingContainer instance = new ScriptingContainer();

或者

ScriptingContainer instance = new ScriptingContainer(LocalVariableBehavior.TRANSIENT)

或者

ScriptingContainer instance = new ScriptingContainer(LocalContextScope.SINGLETHREAD, LocalVariableBehavior.TRANSIENT);

JSR223

System.setProperty("org.jruby.embed.localvariable.behavior", "transient");
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("jruby");

BSF

BSF can choose only BSF type.

3.5.2 Persistent Local Variable Behavior

当选择该种类型时,JRuby Embed会在多次执行中维持本地变量。

Core

ScriptingContainer instance = new ScriptingContainer(LocalVariableBehavior.PERSISTENT);

或者

ScriptingContainer instance = new ScriptingContainer(LocalContextScope.SINGLETHREAD, LocalVariableBehavior

JSR223

System.setProperty("org.jruby.embed.localvariable.behavior", "persistent");
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("jruby");

BSF

BSF can choose only BSF type.

3.5.3 Global Local Variable Behavior

Default for JSR223. This behavior might be convenient to users who have used JSR223 reference implementation released at scripging.dev.java.net and don't want change any code at all. With names like Ruby's local variable name, variables are mapped to Ruby's global variables. Only global variables can be shared between Ruby and Java, when this behavior is chosen. The values of global variables of this type are not kept over the evaluations.

Core

ScriptingContainer instance = new ScriptingContainer(LocalVariableBehavior.GLOBAL);

JSR223

System.setProperty("org.jruby.embed.localvariable.behavior", "global");
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("jruby");

BSF

BSF can choose only BSF type.

3.5.3 BSF Local Variable Behavior

Default for BSF. Local and global variables are available to share between Java and Ruby. Variable names doesn’t start with “$” no matter what the variable types are. Since BSF has a method defined for sharing local variables, it doesn’t confuse. However, core and JSR223 will confuse variables, so don’t use this type for them.

BSF

BSFManager.registerScriptingEngine("jruby", "org.jruby.embed.bsf.JRubyEngine", new String[] {"rb"});
BSFManager manager = new BSFManager();

或者

System.setProperty("org.jruby.embed.localvariable.behavior", "bsf");
BSFManager.registerScriptingEngine("jruby", "org.jruby.embed.bsf.JRubyEngine", new String[] {"rb"});
BSFManager manager = new BSFManager();

3.6 Disabling Sharing Variables

Scope: Per Evaluation Systeom Property Name: org.jruby.embed.sharing.variables Value: true (default), or false

该选项控制变量共享机制是否启用,默认是启用状态。如果置为关闭,那么将会带来些许性能方面的改善。

Core

container.setAttribute(AttributeName.SHARING_VARIABLES, false);

JSR223

System.setProperty("org.jruby.embed.sharing.variables", "false");

3.7 CompileMode

Scope: Per Container Systeme Property Name: org.jruby.embed.compilemode Value: off (default), jit, or force

JRuby has jit and force options to compile Ruby scripts. This configuration provides users a way of setting a compile mode. When jit or force is specified, only a global variable can be shared between Ruby and Java.

This option is not for pre-compiled Ruby scripts. Ruby2java http://kenai.com/projects/ruby2java generated Java classes are not executable on current JRuby Embed.

Core

ScriptingContainer container = new ScriptingContainer();
container.setCompileMode(CompileMode.JIT);

JSR223/BSF

System.setProperty("org.jruby.embed.compilemode", "jit");

3.8 Ruby Version

Scope: Per Container Systemo Property Name: org.jruby.embed.compat.version Value: jruby19, JRuby1_9, ruby1.9….matches j?ruby1[\\._]?9 (case insensitive) 默认版本1.8。如果要用别的版本,那么需要进行设置。如果系统变量值或者注册的名称匹配正则表达式 [jJ]?(r|R)(u|U)(b|B)(y|Y)1[\\\\._]?9,那么将会使用1.9版本来执行ruby脚本。

Core

ScriptingContainer container = new ScriptingContainer();
// JRuby 1.5.x
container.setCompatVersion(CompatVersion.RUBY1_9);
// JRuby 1.4.0
//container.getProvider().getRubyInstanceConfig().setCompatVersion(CompatVersion.RUBY1_9);

JSR223

System.setProperty("org.jruby.embed.compat.version", "JRuby1.9");
JRubyScriptEngineManager manager = new JRubyScriptEngineManager();
JRubyEngine engine = (JRubyEngine) manager.getEngineByName("jruby");

BSF

BSFManager.registerScriptingEngine("jruby19", "org.jruby.embed.bsf.JRubyEngine", new String[] {"rb"});
BSFManager manager = new BSFManager();
manager.exec("jruby19", "ruby/block-param-scope.rb", 0, 0, PathType.CLASSPATH);

3.9 Line Number

Scope: Per Evaluation Context Attribute Name: org.jruby.embed.linenumber Value: 1, 2, 3,,,, (integer)

Embed Core 和 BSF 可以允许通过方法参数来设置显示行号,以追踪解析错误。JSR223的此项设置必须通过上下文属性来进行。

该行号的作用在于设定所解析执行脚本的起始行号。

core

private final String script =
            "puts \"Hello World.\"\n" +
            "puts \"Error is here.";
ScriptingContainer container = new ScriptingContainer();
EvalUnit unit = container.parse(script, 1);
Object ret = unit.run();

JSR223

import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
import org.jruby.embed.jsr223.JRubyScriptEngineManager;

public class LineNumberSample {
    private final String script =
            "puts \"Hello World.\"\n" +
            "puts \"Error is here.";

    private LineNumberSample() throws ScriptException {
        JRubyScriptEngineManager manager = new JRubyScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("jruby");
        try {
            engine.eval(script);    // Since no line number is given, 0 is applied to.
        } catch (Exception e) {
            ;
        }
        try {
            engine.getContext().setAttribute("org.jruby.embed.linenumber", 1, ScriptContext.ENGINE_SCOPE);
            engine.eval(script);
        } catch (Exception e) {
            ;
        }
        try {
            engine.getContext().setAttribute("org.jruby.embed.linenumber", 2, ScriptContext.ENGINE_SCOPE);
            engine.eval(script);
        } catch (Exception e) {
            ;
        }
    }

    public static void main(String[] args)
            throws ScriptException {
        new LineNumberSample();
    }
}

BSF

private final String script =
            "puts \"Hello World.\"\n" +
            "puts \"Error is here.";
BSFManager.registerScriptingEngine("jruby", "org.jruby.embed.bsf.JRubyEngine", new String[] {"rb"});
BSFManager manager = new BSFManager();
manager.exec("jruby", “<script>”, 1, 0, script);

3.10 Other Ruby Runtime Configurations

关于Ruby runtime更多更细致的控制,可以通过Embed Core中org.jruby.RubyInstanceConfig的更多的方法来进行设定。操作举例如下:

ScriptingContainer container = new ScriptingContainer();
RubyInstanceConfig config = container.getProvider().getRubyInstanceConfig();

# First, make the configuration changes you need.
config.someConfigMethod(...);

# Now, you can set variables or run Ruby code.
container.runScriptlet(...);

© 著作权归作者所有

共有 人打赏支持
YuMG
粉丝 7
博文 23
码字总数 78574
作品 0
大连
其他
JRuby 9.1.17.0 发布,改进对 Java 9/10 的兼容性

JRuby 9.1.17.0 已发布,JRuby 是面向 Ruby、基于 Java 虚拟机(JVM)的一种解释程序,它结合了 Ruby 语言的简易性和功能强大的 JVM 的执行机制,包括与 Java 库全面集成。Rails 彻底加快及简化...

王练 ⋅ 04/24 ⋅ 0

HomeCenter 7.87,J2SE/JS+CSS 编写家庭云应用

HomeCenter 7.87 已发布,HomeCenter 是 J2SE/JavaScript+CSS 编写跨平台家庭云应用,实时生成 Android/iPhone 所需的 HTML5+JavaScript+CSS 。 新功能: JRuby 代码编辑器自动检查未定义变量...

Java6 ⋅ 05/28 ⋅ 0

Java 的 Ruby 解释器 - JRuby

JRuby是面向Ruby、基于Java虚拟机(JVM)的一种解释程序,它结合了Ruby语言的简易性和功能强大的JVM的执行机制,包括与Java库 全面集成。Rails彻底加快及简化了Web应用的开发,不过它让人觉得不...

匿名 ⋅ 2008/09/07 ⋅ 2

HotSwap和JRebel原理

HotSwap和JRebel原理 HotSwap和Instrumentation 在2002年的时候,Sun在Java 1.4的JVM中引入了一种新的被称作的实验性技术,这一技术被合成到了内部,其允许调试者使用同一个类标识来更新类的...

千里明月 ⋅ 05/09 ⋅ 0

Kamailio 5.1.2 发布,开源 SIP 服务器

Kamailio SIP Server v5.1.2 stable 已发布,这是一个小的更新版本,包括自 v5.1.1 以来的代码和文档修复。 配置文件和数据库模式的兼容性被保留,这意味着你不需要改变任何东西来更新。 Ka...

王练 ⋅ 03/02 ⋅ 0

Neo4j 的 JRuby 封装--Cadet

Cadet 是使用 JRuby 实现的嵌入式 Neo4j,可以让你方便的在 JRuby 应用中使用 Neo4j。 示例代码: require 'cadet' Cadet::Session.open "path/to/graph.db/" do for a batch inserter sess...

红薯 ⋅ 2014/05/16 ⋅ 0

JRuby 1.4 发布

JRuby 1.4.0发布了!JRuby是Ruby编程语言的100%纯Java实现,它结合了Ruby简洁的语法以及Java丰富的类库。 重要特性: 新的YAML分析器 改进了对java集成的支持 Windows安装程序 新的嵌入式框架...

红薯 ⋅ 2009/11/12 ⋅ 0

JRuby 1.6 正式版发布

JRuby 1.6.0 正式版发布了! 这是 JRuby 目前为止最大的一次版本发布,修复了几千个用户提交的问题,高度的和 Ruby 1.9.2 兼容。该版本集成了目前还体验阶段的 C 扩展,基于 Ruby 的 C API,...

红薯 ⋅ 2011/03/17 ⋅ 0

工具 Burp Suite API学习思路

  Burp Suite是每个web安全学习者都接触过的集成平台,包含集合了多种渗透测试组件,除了强大的功能外,官方还提供API支持使用者开发插件,满足你独特的需求。   0×00 Burp Suite扩展模...

FreeBuf ⋅ 05/14 ⋅ 0

建设DevOps统一运维监控平台,先从日志监控说起

前言 随着Devops、云计算、微服务、容器等理念的逐步落地和大力发展,机器越来越多,应用越来越多,服务越来越微,应用运行基础环境越来多样化,容器、虚拟机、物理机不一而足。 面对动辄几百...

stars永恒 ⋅ 04/26 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Kubeflow实战系列:利用TFJob导出分布式TensorFlow模型

介绍 本系列将介绍如何在阿里云容器服务上运行Kubeflow, 本文介绍如何使用TfJob导出分布式模型训练模型。 第一篇:阿里云上使用JupyterHub 第二篇:阿里云上小试TFJob 第三篇:利用TFJob运行...

全部原谅 ⋅ 20分钟前 ⋅ 0

007. 深入JVM学习—老年代

老年代空间的主要目的是用于存储由Eden发送来的对象,一般在经历好几次“Minor GC”还会保存下来的对象,才会被复制到老年代,这样就可以存放更多的对象,同时在老年代中执行GC的次数也相对较...

影狼 ⋅ 21分钟前 ⋅ 0

常见的一些C#开源框架或者开源项目

原:https://blog.csdn.net/qq_27825451/article/details/70666044 Json.NET http://json.codeplex.com/ Json.Net 是一个读写Json效率比较高的.Net框架.Json.Net 使得在.Net环境下使用Json更......

whoisliang ⋅ 22分钟前 ⋅ 0

设计模式基本原理

刚开始接触编程这行的时候看过设计模式,当时感觉学这些模式没有太大的用处,当时也看不太懂。但是随着慢慢接触这一行,经过一段时间的编程以后,再回过头来看设计模式,发现设计模式的确是太...

王子城 ⋅ 25分钟前 ⋅ 0

阿里云全面支持IPv6!一文揽尽4位大咖精彩演讲

摘要: 自从去年11月以来,阿里巴巴高度重视数据中心的网络改造、云产品改造、应用及网络改造等多个维度,经过半年以来的建设,阿里云已经完成了域名解析等关键产品的分析,现在阿里云已经完...

传授知识的天使 ⋅ 35分钟前 ⋅ 0

windows Android sdk 配置

1、下载Android SDK,点击安装,直接默认路径即可! 下载地址:http://developer.android.com/sdk/index.html 2、默认路径安装后,安装完成,开始配置环境变量。 3、打开计算机属性——高级系...

阿豪boy ⋅ 38分钟前 ⋅ 0

bash shell script 简明教程

User <--> bash <--> kernel shell is not kernel or part of kernel various shells: tcsh, csh, bash, ksh find the using shell: echo $SHELL find all the shells: cat /etc/shells what......

mskk ⋅ 41分钟前 ⋅ 0

Service Mesh简史

William Morgan Service Mesh是一个相当新的概念,讲它的“历史”似乎有些勉强。就目前而言,Service Mesh已经在部分企业生产环境中运行了超过18个月,它的源头可以追溯到2010年前后互联网公...

好雨云帮 ⋅ 41分钟前 ⋅ 0

10个免费的服务器监控工具

监控你的WEB服务器或者WEB主机运行是否正常与健康是非常重要的。你要确保用户始终可以打开你的网站并且网速不慢。服务器监控工具允许你收集和分析有关你的Web服务器的数据。 有许多非常好的服...

李朝强 ⋅ 53分钟前 ⋅ 0

压缩工具之zip-tar

zip 支持目录压缩。使用yum安装zip包,使用yum安装unzip包 zip 1.txt.zip 1.txt #将1.txt文件压缩,新生成的压缩文件为1.txt.zip,原文件保留 zip -r 123.zip 123/ #-r对目录操作。将123/目录...

ZHENG-JY ⋅ 54分钟前 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部