2007 年 9 月 14 日
我們不
需要將動態(tài)語言編譯為 Java? 字節(jié)碼就可以在 Java 應用程序中使用它們,。使用 Java Platform, Standard
Edition 6 (Java SE)中添加的腳本包(并且向后兼容 Java SE 5),Java
代碼可以在運行時以一種簡單的,、統(tǒng)一的方式調用多種動態(tài)語言,。本系列文章共分兩個部分,第 1 部分將介紹 Java 腳本 API
的各種特性,。文章將使用一個簡單的 Hello World 應用程序展示 Java 代碼如何執(zhí)行腳本代碼以及腳本如何反過來執(zhí)行 Java 代碼,。第
2 部分將深入研究 Java 腳本 API 的強大功能。
Java 開發(fā)人員清楚 Java 并不是在任何情況下都是最佳的語言,。今年,,1.0 版本的 JRuby 和
Groovy 的發(fā)行引領了一場熱潮,促使人們紛紛在自己的 Java 應用程序中添加動態(tài)語言,。Groovy,、JRuby、Rhino,、Jython
和一些其他的開源項目使在所謂的腳本語言中編寫代碼并在 JVM 中運行成為了可能(請參閱 參
考資料),。通常,在 Java 代碼中集成這些語言需要對各種解釋器所特有的 API 和特性有所了解,。
Java SE 6 中添加的 javax.script
包使集成動態(tài)語言更加容易,。通過使用一小組接口和具體類,這個包使我們能夠簡單地調用多種腳本語言,。但是,,Java 腳本 API
的功能不只是在應用程序中編寫腳本;這個腳本包使我們能夠在運行時讀取和調用外部腳本,,這意味著我們可以動態(tài)地修改這些腳本從而更改運行應用程序的行為,。
Java 腳本 API
|
腳本與動態(tài)的對比
術語腳本 通常表示在解釋器 shell 中運行的語言,它們往往沒有單獨的編譯步驟,。術語動
態(tài) 通常表示等到運行時判斷變量類型或對象行為的語言,,往往具有閉包和連續(xù)特性。一些通用的編程語言同時具有這兩種特性,。此處首選腳本語言
是因為本文的著重點是 Java 腳本 API,,而不是因為提及的語言缺少動態(tài)特性,。
|
|
2006 年 10 月,Java 語言添加了腳本包,,從而提供了一種統(tǒng)一的方式將腳本語言集成到 Java
應用程序中去,。對于語言開發(fā)人員,他們可以使用這個包編寫粘連代碼(glue code),,從而使人們能夠在 Java 應用程序中調用他們的語言,。對于
Java 開發(fā)人員,腳本包提供了一組類和接口,,允許使用一個公共 API
調用多種語言編寫的腳本,。因此,腳本包類似于不同語言(比如說不同的數(shù)據(jù)庫)中的 Java Database Connectivity (JDBC)
包,,可以使用一致的接口集成到 Java 平臺中去,。
以前,在 Java 代碼中,,動態(tài)調用腳本語言涉及到使用各種語言發(fā)行版所提供的獨特類或使用 Apache 的
Jakarta Bean Scripting Framework (BSF),。BSF 在一個 API 內部統(tǒng)一了一組腳本語言(請參閱 參
考資料)。使用 Java SE 6 腳本
API,,二十余種腳本語言(AppleScript,、Groovy、JavaScript,、Jelly,、PHP、Python,、Ruby 和
Velocity)都可以集成到 Java 代碼中,,這在很大程序上依賴的是 BSF。
腳本 API 在 Java 應用程序和外部腳本之間提供了雙向可見性,。Java
代碼不僅可以調用外部腳本,,而且還允許那些腳本訪問選定的 Java 對象。比如說,,外部 Ruby 腳本可以對 Java
對象調用方法,,并訪問對象的屬性,從而使腳本能夠將行為添加到運行中的應用程序中(如果在開發(fā)時無法預計應用程序的行為),。
調用外部腳本可用于運行時應用程序增強,、配置、監(jiān)控或一些其他的運行時操作,,比如說在不停止應用程序的情況下修改業(yè)務規(guī)
則,。腳本包可能的作用包括:
- 在比 Java 語言更簡單的語言中編寫業(yè)務規(guī)則,而不用借助成熟的規(guī)則引擎。
- 創(chuàng)建插件架構,,使用戶能夠動態(tài)地定制應用程序,。
- 將已有腳本集成到 Java 應用程序中,比如說處理或轉換文件文章的腳本,。
- 使用成熟的編程語言(而不是屬性文件)從外部配置應用程序的運行時行為,。
- 在 Java 應用程序中添加一門特定于域的語言(domain-specific language)。
- 在開發(fā) Java 應用程序原型的過程中使用腳本語言,。
- 在腳本語言中編寫應用程序測試代碼,。
你好,腳本世界
HelloScriptingWorld 類(本文中的相關代碼均可從 下
載部分 獲得)演示了 Java 腳本包的一些關鍵特性,。它使用硬編碼的 JavaScript 作為示例腳本語言。此類的 main()
方法(如清單 1 所示)將創(chuàng)建一個 JavaScript 腳本引擎,,然后分別調用五個方法(在下文的清單中有顯示)用于突出顯示腳本包的特性,。
清單 1. HelloScriptingWorld main 方法
public static void main(String[] args) throws ScriptException, NoSuchMethodException {
ScriptEngineManager scriptEngineMgr = new ScriptEngineManager();
ScriptEngine jsEngine = scriptEngineMgr.getEngineByName("JavaScript");
if (jsEngine == null) {
System.err.println("No script engine found for JavaScript");
System.exit(1);
}
System.out.println("Calling invokeHelloScript...");
invokeHelloScript(jsEngine);
System.out.println("\nCalling defineScriptFunction...");
defineScriptFunction(jsEngine);
System.out.println("\nCalling invokeScriptFunctionFromEngine...");
invokeScriptFunctionFromEngine(jsEngine);
System.out.println("\nCalling invokeScriptFunctionFromJava...");
invokeScriptFunctionFromJava(jsEngine);
System.out.println("\nCalling invokeJavaFromScriptFunction...");
invokeJavaFromScriptFunction(jsEngine);
}
|
main() 方法的主要功能是獲取一個 javax.script.ScriptEngine
實例(清
單 1 中的前兩行代碼)。腳本引擎可以在特定的語言中加載并執(zhí)行腳本,。它是 Java 腳本包中使用最為頻繁,、作用最為重要的類。我們從 javax.script.ScriptEngineManager
獲取一個腳本引擎(第一行代碼),。通常,,程序只需要獲取一個腳本引擎實例,除非使用了很多種腳本語言,。
ScriptEngineManager
類
ScriptEngineManager
可能是腳本包中惟一一個經(jīng)常使用的具體類,;其他大多數(shù)都是接口。它或許是腳本包中惟一的一個要直接或間接地(通過 Spring Framework
之類的依賴性注入機制)實例化的類,。ScriptEngineManager 可以使用以下三種方式返回腳本引擎:
- 通過引擎或語言的名稱,,比如說 清
單 1 請求
JavaScript 引擎。
- 通過該語言腳本共同使用的文件擴展名,,比如說 Ruby 腳本的 .rb,。
- 通過腳本引擎聲明的、知道如何處理的 MIME 類型,。
|
本文示例為什么要使用 JavaScript,?
本文中的 Hello World 示例使用了部分 JavaScript 腳本,這是因為
JavaScript 代碼易于理解,,不過主要還是因為 Sun Microsystems 和 BEA Systems 所提供的 Java 6
運行時環(huán)境附帶有基于 Mozilla Rhino 開源 JavaScript 實現(xiàn)的 JavaScript 解釋器,。使用
JavaScript,,我們無需在類路徑中添加腳本語言 JAR 文件,。
|
|
ScriptEngineManager
間接查找和創(chuàng)建腳本引擎。也就是說,,當實例化腳本引擎管理程序時,ScriptEngineManager 會使用 Java 6
中新增的服務發(fā)現(xiàn)機制在類路徑中查找所有注冊的 javax.script.ScriptEngineFactory
實現(xiàn),。這些工廠類封裝在 Java 腳本 API 實現(xiàn)中,;也許您永遠都不需要直接處理這些工廠類。
ScriptEngineManager
找到所有的腳本引擎工廠類之后,,它會查詢各個類并判斷是否能夠創(chuàng)建所請求類型的腳本引擎 —— 清
單 1 中為 JavaScript
引擎,。如果工廠說可以創(chuàng)建所需語言的腳本引擎,那么管理程序將要求工廠創(chuàng)建一個引擎并將其返回給調用者,。如果沒有找到所請求語言的工廠,,那么管理程序將返
回 null ,清
單 1 中的代碼將檢查 null 返回值并做出預防,。
ScriptEngine 接口
如前所述,,代碼將使用 ScriptEngine
實例執(zhí)行腳本。腳本引擎充當腳本代碼和最后執(zhí)行代碼的底層語言解釋器或編譯器之間的中間程序,。這樣,,我們就不需要了解各個解釋器使用哪些類來執(zhí)行腳本。比
如說,,JRuby 腳本引擎可以將代碼傳遞給 JRuby 的 org.jruby.Ruby
類的一個實例,,首先將腳本編譯成中間形式,然后再調用它計算腳本并處理返回值,。腳本引擎實現(xiàn)隱藏了一些細節(jié),,包括解釋器如何與 Java
代碼共享類定義、應用程序對象和輸入/輸出流,。
圖 1 顯示了應用程序,、Java 腳本 API 和 ScriptEngine
實現(xiàn)、腳本語言解釋器之間的總體關系,。我們可以看到,,應用程序只依賴于腳本 API,它提供了 ScriptEngineManager
類和 ScriptEngine 接口,。ScriptEngine
實現(xiàn)組件處理使用特定腳本語言解釋器的細節(jié),。
圖 1:腳本 API 組件關系
您可能會問:如何才能獲取腳本引擎實現(xiàn)和語言解釋器所需的 JAR 文件呢?最好的方法是在
上托管的開源 Scripting 項目中查找腳本引擎實現(xiàn)(請參閱 參
考資料),。您可以在 上找到許多語言的腳本引擎實現(xiàn)和其他網(wǎng)站的鏈接,。Scripting
項目還提供了各種鏈接,通過這些鏈接可以下載受支持的腳本語言的解釋器,。
在 清
單 1 中,,main() 方法將 ScriptEngine
傳遞給各個方法用于計算該方法的 JavaScript 代碼。第一個方法如清單 2 所示,。invokeHelloScript()
方法調用腳本引擎的 eval 方法計算和執(zhí)行 JavaScript 代碼中的特定字符串,。ScriptEngine
接口定義了 6 個重載的 eval() 方法,,用于將接收的腳本當作字符串或 java.io.Reader
對象計算,java.io.Reader 對象一般用于從外部源(例如文件)讀取腳本,。
清單 2. invokeHelloScript 方法
private static void invokeHelloScript(ScriptEngine jsEngine) throws ScriptException {
jsEngine.eval("println('Hello from JavaScript')");
}
|
|
腳本執(zhí)行上下文
HelloScriptingWorld 應用程序中的示例腳本 使用
JavaScript println()
函數(shù)向控制臺輸出結果,,但是我們擁有輸入和輸出流的完全控制權。腳本引擎提供了一個選項用于修改腳本執(zhí)行的上下文,,這意味著我們可以修改標
準輸入流,、標準輸出流和標準錯誤流,同時還可以定義哪些全局變量和 Java 對象對正在執(zhí)行的腳本可用,。
|
|
invokeHelloScript() 方法中的 JavaScript 將 Hello
from JavaScript 輸出到標準輸出流,,在本例中為控制臺窗口。(清
單 6 含有運行 HelloScriptingWorldApplication 時的完整輸出,。)
注意,,類中的這一方法和其他方法都聲明拋出了 javax.script.ScriptException 。
這個選中的異常(腳本包中定義的惟一一個異常)表示引擎無法解析或執(zhí)行給定的代碼,。所有腳本引擎 eval()
方法都聲明拋出一個 ScriptException ,,因此我們的代碼需要適當處理這些異常。
清單 3 顯示了兩個有關的方法:defineScriptFunction() 和 invokeScriptFunctionFromEngine() ,。defineScriptFunction()
方法還使用一段硬編碼的 JavaScript 代碼調用腳本引擎的 eval()
方法。但是有一點需要注意,,該方法的所有工作只是定義了一個 JavaScript 函數(shù) sayHello() ,。并沒有執(zhí)行
任何代碼。sayHello() 函數(shù)只有一個參數(shù),,它會使用 println()
語句將這個參數(shù)輸出到控制臺,。腳本引擎的 JavaScript 解釋器將這個函數(shù)添加到全局環(huán)境,以供后續(xù)的 eval
調用使用(該調用發(fā)生在 invokeScriptFunctionFromEngine() 方法中,,這并不奇怪)。
清單 3. defineScriptFunction 和
invokeScriptFunctionFromEngine 方法
private static void defineScriptFunction(ScriptEngine engine) throws ScriptException {
// Define a function in the script engine
engine.eval(
"function sayHello(name) {" +
" println('Hello, ' + name)" +
"}"
);
}
private static void invokeScriptFunctionFromEngine(ScriptEngine engine)
throws ScriptException
{
engine.eval("sayHello('World!')");
}
|
這兩個方法演示了腳本引擎可以維持應用程序組件的狀態(tài),,并且能夠在后續(xù)的 eval()
方法調用過程中使用其狀態(tài),。invokeScriptFunctionFromEngine()
方法可以利用所維持的狀態(tài),方法是調用定義在 eval() 調用中的 sayHello()
JavaScript 函數(shù),。
許多腳本引擎在 eval()
調用之間維持全局變量和函數(shù)的狀態(tài),。但是有一點值得格外注意,Java 腳本 API 并不要求腳本引擎提供這一特性,。本文中所使用的
JavaScript,、Groovy 和 JRuby 腳本引擎確實在 eval() 調用之間維持了這些狀態(tài)。
清單 4 中的代碼在前一個示例的基礎上做了幾分修改,。原來的 invokeScriptFunctionFromJava()
方法在調用 sayHello() JavaScript 函數(shù)時沒有使用 ScriptEngine
的 eval() 方法或 JavaScript
代碼,。與此不同,,清單 4 中的方法使用 Java 腳本 API 的 javax.script.Invocable
接口調用由腳本引擎所維持的函數(shù)。invokeScriptFunctionFromJava() 方法將腳本引擎對象傳遞給
Invocable 接口,,然后對該接口調用 invokeFunction()
方法,,最終使用給定的參數(shù)調用 sayHello() JavaScript 函數(shù)。如果調用的函數(shù)需要返回值,,則 invokeFunction()
方法會將值封裝為 Java 對象 類型并返回,。
清單 4. invokeScriptFunctionFromJava
方法
private static void invokeScriptFunctionFromJava(ScriptEngine engine)
throws ScriptException, NoSuchMethodException
{
Invocable invocableEngine = (Invocable) engine;
invocableEngine.invokeFunction("sayHello", "from Java");
}
|
|
使用代理實現(xiàn)高級腳本調用
當腳本函數(shù)或方法實現(xiàn)了一個 Java 接口時,就可以使用高級 Invocable ,。Invocable
接口定義了一個 getInterface() 方法,,該方法使用接口做為參數(shù)并且將返回一個實現(xiàn)該接口的 Java
代碼對象。從腳本引擎獲得代理對象之后,,可以將它作為正常的 Java 對象對待,。對該代理調用的方法將委托給腳本引擎通過腳本語言執(zhí)行。
|
|
注意,,清
單 4 中沒有 JavaScript 代碼,。Invocable 接口允許 Java
代碼調用腳本函數(shù),而無需知道其實現(xiàn)語言,。如果腳本引擎無法找到給定名稱或參數(shù)類型的函數(shù),,那么 invokeFunction()
方法將拋出一個 java.lang.NoSuchMethodException 。
Java 腳本 API 并不要求腳本引擎實現(xiàn) Invocable 接口,。實際上,,清
單 4 中的代碼應該使用 instanceof 運算符確保腳本引擎在轉換(cast)之前實現(xiàn)了 Invocable
接口。
通過腳本代碼調用 Java
方法
清
單 3 和 清
單 4 中的示例展示了 Java 代碼如何調用腳本語言中定義的函數(shù)或方法,。您可能會問:腳本語言中編寫的代碼是否可以反過來對 Java
對象調用方法呢,?答案是可以。清單 5 中的 invokeJavaFromScriptFunction()
方法顯示了如何使腳本引擎能夠訪問 Java 對象,,以及腳本代碼如何才能對這些 Java 對象調用方法,。明確的說,invokeJavaFromScriptFunction()
方法使用腳本引擎的 put() 方法將 HelloScriptingWorld
類的實例本身提供給引擎,。當引擎擁有 Java 對象的訪問權之后(使用 put() 調用所提供的名稱),,eval()
方法腳本中的腳本代碼將使用該對象。
清單 5.
invokeJavaFromScriptFunction 和 getHelloReply 方法
private static void invokeJavaFromScriptFunction(ScriptEngine engine)
throws ScriptException
{
engine.put("helloScriptingWorld", new HelloScriptingWorld());
engine.eval(
"println('Invoking getHelloReply method from JavaScript...');" +
"var msg = helloScriptingWorld.getHelloReply(vJavaScript');" +
"println('Java returned: ' + msg)"
);
}
/** Method invoked from the above script to return a string. */
public String getHelloReply(String name) {
return "Java method getHelloReply says, 'Hello, " + name + "'";
}
|
清
單 5 中的 eval() 方法調用中所包含的 JavaScript 代碼使用腳本引擎的 put()
方法調用所提供的變量名稱 helloScriptingWorld 訪問并使用 HelloScriptingWorld
Java 對象,。清
單 5 中的第二行 JavaScript 代碼將調用 getHelloReply() 公有 Java 方法,。getHelloReply()
方法將返回 Java method getHelloReply says, 'Hello,
<parameter>' 字符串。eval() 方法中的 JavaScript 代碼將
Java 返回值賦給 msg 變量,,然后再將其打印輸出給控制臺,。
|
Java 對象轉換
當腳本引擎使運行于引擎環(huán)境中的腳本能夠使用 Java
對象時,引擎需要將其封裝到適用于該腳本語言的對象類型中,。封裝可能會涉及到一些適當?shù)膶ο螅缔D換,,比如說允許 Java Integer
對象直接在腳本語言的數(shù)學表達式中使用,。關于如何將 Java
對象轉換為腳本對象的研究是與各個腳本語言的引擎特別相關的,并且不在本文的討論范圍之內,。但是,,您應該意識到轉換的發(fā)生,因為可以通過測試來確保所使用
的腳本語言執(zhí)行轉換的方式符合您的期望,。
|
|
ScriptEngine.put 及其相關 get()
方法是在運行于腳本引擎中的 Java 代碼和腳本之間共享對象和數(shù)據(jù)的主要途徑,。(有關這一方面的詳細論述,請參閱本文后面的 Script-execution
scope 一節(jié),。)當我們調用引擎的 put() 方法時,,腳本引擎會將第二個參數(shù)(任何 Java
對象)關聯(lián)到特定的字符串關鍵字。大多數(shù)腳本引擎都是讓腳本使用特定的變量名稱來訪問 Java 對象,。腳本引擎可以隨意對待傳遞給 put()
方法的名稱,。比如說,JRuby 腳本引擎讓 Ruby 代碼使用全局 $helloScriptingWorld
對象訪問 helloScriptingWorld ,,以符合 Ruby 全局變量的語法,。
腳本引擎的 get() 方法檢索腳本環(huán)境中可用的值。一般而言,,Java 代碼通過 get()
方法可以訪問腳本環(huán)境中的所有全局變量和函數(shù),。但是只有明確使用 put() 與腳本共享的 Java
對象才可以被腳本訪問。
外部腳本在運行著的應用程序中訪問和操作 Java 對象的這種功能是擴展 Java 程序功能的一項強有力的技巧,。(第
2 部分將通過示例研究這一技巧),。
運行 HelloScriptingWorld 應用程序
您可以通過下載和構建源代碼來運行 HelloScriptingWorld 應用程序。此 .zip 中文件含有一個
Ant 腳本和一個 Maven 構建腳本,,可以幫助大家編譯和運行示例應用程序。請執(zhí)行以下步驟:
-
下
載 此 .zip 文件,。
- 創(chuàng)建一個新目錄,,比如說 java-scripting,并將步驟 1 中所下載的文件解壓到該目錄中,。
- 打開命令行 shell 并轉到該目錄,。
- 運行
ant run-hello 命令。
您應該可以看到類似于清單 6 的 Ant 控制臺輸出,。注意,,defineScriptFunction()
函數(shù)沒有產生任何輸出,因為它雖然定義了輸出但是卻沒有調用 JavaScript 函數(shù),。
清單 6. 運行 HelloScriptingWorld 時的輸出
Calling invokeHelloScript...
Hello from JavaScript
Calling defineScriptFunction...
Calling invokeScriptFunctionFromEngine...
Hello, World!
Calling invokeScriptFunctionFromJava...
Hello, from Java
Calling invokeJavaFromScriptFunction...
Invoking getHelloReply method from JavaScript...
Java returned: Java method getHelloReply says, 'Hello, JavaScript'
|
Java 5 兼容性
Java SE 6 引入了 Java 腳本 API,,但是您也可以使用 Java SE 5 運行此
API。只需要提供缺少的 javax.script 包類的一個實現(xiàn)即可,。所幸的是,,Java Specification
Request 223 參考實現(xiàn)中含有這個實現(xiàn)(請參閱 參
考資料 獲得下載鏈接,。)JSR 223 對 Java 腳本 API 做出了定義。
如果您已經(jīng)下載了 JSR 223 參考實現(xiàn),,解壓下載文件并將
script-api.jar,、script-js.jar 和 js.jar 文件復制到您的類路徑下。這些文件將提供腳本
API,、JavaScript 腳本引擎接口和 Java SE 6 中所附帶的 JavaScript 腳本引擎,。
腳本執(zhí)行作用域
與簡單地調用引擎的 get() 和 put()
方法相比,如何將 Java 對象公開給運行于腳本引擎中的腳本具有更好的可配置性,。當我們在腳本引擎上調用 get() 或
put() 方法時,,引擎將會在 javax.script.Bindings
接口的默認實例中檢索或保存所請求的關鍵字。(Bindings 接口只是一個 Map
接口,,用于強制關鍵字為字符串,。)
當代碼調用腳本引擎的 eval()
方法時,將使用引擎默認綁定的關鍵字和值,。但是,,您可以為 eval() 調用提供自己的 Bindings
對象,以限制哪些變量和對象對于該特定腳本可見,。該調用外表上類似于 eval(String, Bindings) 或 eval(Reader,
Bindings) ,。要幫助您創(chuàng)建自定義的 Bindings ,腳本引擎將提供一個 createBindings()
方法,,該方法和返回值是一個內容為空的 Bindings 對象,。使用 Bindings
對象臨時調用 eval 將隱藏先前保存在引擎默認綁定中的 Java 對象。
要添加功能,,腳本引擎含有兩個默認綁定:其一為 get() 和 put()
調用所使用的 “引擎作用域” 綁定 ,;其二為 “全局作用域” 綁定,當無法在 “引擎作用域”
中找到對象時,,引擎將使用第二種綁定進行查找,。腳本引擎并不需要使腳本能夠訪問全局綁定。大多數(shù)腳本都可以訪問它,。
“全局作用域” 綁定的設計目的是在不同的腳本引擎之間共享對象,。ScriptEngineManager
實例返回的所有腳本引擎都是 “全局作用域” 綁定對象。您可以使用 getBindings(ScriptContext.GLOBAL_SCOPE)
方法檢索某個引擎的全局綁定,,并且可以使用 setBindings(Bindings,
ScriptContext.GLOBAL_SCOPE) 方法為引擎設置全局綁定,。
ScriptContext 是一個定義和控制腳本引擎運行時上下文的接口。腳本引擎的 ScriptContext
含有 “引擎” 和 “全局” 作用域綁定,,以及用于標準輸入和輸出操作的輸入和輸出流,。您可以使用引擎的 getContext()
方法獲取并操作腳本引擎的上下文。
一些腳本 API 概念,,比如說作用域,、綁定 和上下文,,開始看來會令人迷
惑,因為它們的含義有交叉的地方,。本文的源代碼下載文件含有一個名為 ScriptApiRhinoTest 的 JUnit 測試文件,,位于
src/test/java directory 目錄,該文件可以通過 Java 代碼幫助解釋這些概念,。
未來的計劃
現(xiàn)在,,大家已經(jīng)對 Java 腳本 API 有了最基本的認識,本系列文章的第 2
部分將在此基礎上進行擴展,,為大家演示一個更為實際的示例應用程序,。該應用程序將使用 Groovy、Ruby 和 JavaScript
一起編寫的外部腳本文件來定義可在運行時修改的業(yè)務邏輯,。如您如見,,在腳本語言中定義業(yè)務規(guī)則可以使規(guī)則的編寫更加輕松,并且更易于程序員之外的人員閱
讀,,比如說業(yè)務分析師或規(guī)則編寫人員,。
下載
描述 | 名字 | 大小 | 下載方法 |
源代碼和 JAR 文件 |
j-javascripting1.zip |
116KB |
HTTP |
參考資料
學習
- 您
可以參閱本文在 developerWorks 全球站點上的 英文原文 。
-
developerWorks 文章“給
Java SE 注入腳本語言的活力”:介紹了在 Java SE6(Mustang)中所增加的對腳本語言的支持功能,。
-
JSR-223:
Scripting for the Java Platform:該 JSR 對添加到 Java SE 6 中的 Java 腳本 API
做出了定義,。
-
Java
腳本程序員指南:Sun 公司的 JDK 6 文檔,其中含有 Java 腳本 API 的程序員指南,。
-
Jakarta Bean
Scripting Framework:BSF 項目為 Java 腳本 API 提供了基石,。
-
“Making
Scripting Languages JSR-223-Aware”(Thomas Künneth, , 2006 年
9 月):這篇文章介紹了當沒有腳本引擎可用時如何在 Java 腳本 API 中使用腳本語言。
-
Groovy:從
Groovy 項目站點了解更多有關 Groovy 的知識,,它是一種用于 Java 平臺的敏捷的動態(tài)語言,。
-
實戰(zhàn) Groovy
:要深入研究 Groovy,可以閱讀 developerWorks 系列文章,。
-
Mozilla Rhino:
其中含有大量與 JavaScript 引擎有關的文檔和參考資料,,Sun Microsystems 和 BEA Systems 的 Java
運行時綁定了 JavaScript 引擎。
-
JRuby:JRuby 是
Ruby 編程語言的純 Java 實現(xiàn),。其項目 Web 站點含有最新的項目新聞和有關 JRuby 使用的參考資料。
- 瀏覽 技術
書店 獲得關于各類技術專題的書籍,。
-
developerWorks
Java 技術專區(qū):數(shù)百篇關于 Java 編程各個方面的文章,。
獲得產品和技術
-
Groovy:
下載最新的 Groovy 發(fā)行版。
-
Java
SE 6 和 BEA
JRockit:內部支持 Java 腳本 API 的開發(fā)包和運行時環(huán)境,,其中含有一個簡化版本的 Mozilla Rhino
JavaScript 引擎,。
-
Scripting 項目:
上的開源 Scripting 項目提供了二十余種語言的腳本引擎接口,和其他一些知名 Java
腳本引擎的鏈接,。要使用其中的腳本語言,,需要安裝此項目中的腳本引擎實現(xiàn) JAR 文件,,和腳本語言解釋器 JAR 文件。
-
Scripting
for the Java Platform 1.0 參考實現(xiàn):JSR-223 參考實現(xiàn)提供了三個 JAR 文件,,允許 Java 腳本
API 在 Java SE 5 中運行,。下載并解壓 sjp-1_0-fr-ri.zip 文件,然后將 js.jar,、script-api.jar
和 script-js.jar 文件放置在類路徑下,。
討論
關于作者
|
|
|
Tom McQueeney 是 Idea Integration(美國的一家咨詢公司)的一名 Java
開發(fā)人員和應用程序架構師,。他熱衷于將一些動態(tài)語言(如 Ruby 和 Groovy)集成到 Java
項目中,,從而提高開發(fā)的速度、效率和樂趣,。他曾經(jīng)是 O'Reilly OSCON 和 ApacheCon EuropeHe 的發(fā)言人,,并且擔任過
Denver Java Users Group 的總裁一職。他和他的妻子(也是一名認證的 Java 架構師)居住在華盛頓,。
|
|